Langere tijd vraag ik me al af of het mogelijk is om SQL een beetje intelligenter te maken dan het is dmv bepaalde parse-logica in een SQL statement uit te voeren. Misschien dat nu bij sommige mensen de haren rechtop gaan staan omdat ze vinden dat je SQL zo dom mogelijk moet houden en alle parse-acties en business rules in de BL en DL moet afchecken, maar ik vind ook dat het filteren van data wel in SQL mag, en als daar deels intelligentie bij komt kijken.... vind ik dat niet erg. Enfin, om dit niet naar een discussie te laten verlopen in de zin van of het wel of niet mooi/gepast o.i.d. is, sla ik dit gewoon over en ga weer verder met de hoofdzaak.
Ik heb een header tabel, ongeveer als volgt:
En een analyse tabel die een 1:n relatie heeft met de header tabel:
Wat ik nu wil is het volgt; voor elke id in de header tabel voor ik wat subqueries uit, welke de count per status retourneren. "1A/3B/1C/1D/1E" als AnalysesForID en "7" als TotalCount voor headerID 1 en "2B/1C" en "1" voor headerID 2.
Nu ben ik aant stoeien geweest met SQL , en nu kom ik in feite al tot dit punt. Hiervoor gebruik ik de volgende code:
Probleem is echter als van een bepaalde analyse 0 counts zijn, dat ik dan ipv "0A/2B/1C/0D/0E" en "3" terugkrijg voor headerID 2, maar dat ik dan wil dat hij me de 0 waarden niet laat zien, en ik dan dus alleen de string "2B/1C" terug wil krijgen zoals boven gezegd.
ik kan echter geen variabelen aanmaken met DECLARE, omdat je die buiten de select moet SET-ten, en aangezien ik voor élke ID in tHeader deze data terug wil krijgen, moet dat ook binnen de SELECT blijven staan, en SET binnenin een SELECT mag niet volgens MS-SQL.
Returnvariabelen na een subquery kunnen ook niet want die kunnen niet uitgevoerd worden, hoewel de SQL wél parsebaar is
, omdat hij dan de column niet kan vinden.
Mini voorbeeldje:
De SQL parsed wel zonder problemen, alleen bij executen ervan krijg ik dan de fout "Invalid column name 'aCount'". Eenzelfde melding die ik zou krijgen als ik een IF statement zou gebruiken.
In pseudocode zou ik iig ongeveer de volgende stappen aanhouden:
count(aStatussen)
count(bStatussen)
count(cStatussen)
count(dStatussen)
count(eStatussen)
als aStatussen > 0 dan strStatus = aStatussen + 'A'
als strStatus <> '' dan strStatus += '/'
als bStatussen > 0 dan strStatus += bStatussen + 'B'
als strStatus <> '' dan strStatus += '/'
als cStatussen > 0 dan strStatus += cStatussen + 'C'
als strStatus <> '' dan strStatus += '/'
als dStatussen > 0 dan strStatus += dStatussen + 'D'
als strStatus <> '' dan strStatus += '/'
als eStatussen > 0 dan strStatus += eStatussen + 'E'
als Substring(strStatus, Length(strStatus) -1) == '/' dan strStatus = Substring(strStatus, 0, Length(strStatus) -1)
Ik begin langzaam te twijfelen óf dit wel in SQL mogelijk is, in C# is het achteraf gezien op de DataTable wel mogelijk, maar ik zou het mooi vinden als ik vanuit SQL gewoon in 1x een correcte returnwaarde krijg.
Mijn vraag aan de rest van jullie Tweakers is dan nu ook of hetgene wat ik wil wel mogelijk is met SQL? En of iemand me dan ook kan helpen hiermee? Want zelf zit ik dus gigantisch vast hier.
Ja, het is een lange topicstart, maar ik hoop wel zo alles heel duidelijk te hebben weergegeven
Ik heb een header tabel, ongeveer als volgt:
| ID | Naam |
| 1 | Hans |
| 2 | Piet |
En een analyse tabel die een 1:n relatie heeft met de header tabel:
| ID | HeaderID | Analyse |
| 1 | 1 | A |
| 2 | 1 | B1 |
| 3 | 1 | B2 |
| 4 | 1 | B4 |
| 5 | 1 | C |
| 6 | 1 | D |
| 7 | 1 | E |
| 8 | 2 | B1 |
| 9 | 2 | B3 |
| 10 | 2 | C |
Wat ik nu wil is het volgt; voor elke id in de header tabel voor ik wat subqueries uit, welke de count per status retourneren. "1A/3B/1C/1D/1E" als AnalysesForID en "7" als TotalCount voor headerID 1 en "2B/1C" en "1" voor headerID 2.
Nu ben ik aant stoeien geweest met SQL , en nu kom ik in feite al tot dit punt. Hiervoor gebruik ik de volgende code:
SQL:
1
2
3
4
5
6
7
8
| SELECT (CAST((SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID) AND (Analyse = 'A')) AS NVARCHAR) + 'A/' + CAST((SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID) AND (Analyse LIKE 'B_')) AS NVARCHAR) + 'B/' + CAST((SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID) AND (Analyse = 'C')) AS NVARCHAR) + 'C/' + CAST((SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID) AND (Analyse = 'D')) AS NVARCHAR) + 'D/' + CAST((SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID) AND (Analyse = 'E')) AS NVARCHAR) + 'E') AS AnalysesForID, (SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID)) AS TotalCount FROM tHeader |
Probleem is echter als van een bepaalde analyse 0 counts zijn, dat ik dan ipv "0A/2B/1C/0D/0E" en "3" terugkrijg voor headerID 2, maar dat ik dan wil dat hij me de 0 waarden niet laat zien, en ik dan dus alleen de string "2B/1C" terug wil krijgen zoals boven gezegd.
ik kan echter geen variabelen aanmaken met DECLARE, omdat je die buiten de select moet SET-ten, en aangezien ik voor élke ID in tHeader deze data terug wil krijgen, moet dat ook binnen de SELECT blijven staan, en SET binnenin een SELECT mag niet volgens MS-SQL.
Returnvariabelen na een subquery kunnen ook niet want die kunnen niet uitgevoerd worden, hoewel de SQL wél parsebaar is
Mini voorbeeldje:
SQL:
1
2
| (SELECT COUNT(*) FROM tAnalyses WHERE (headerID = tHeader.ID) AND (Analyse = 'A')) AS aCount, (CAST(aCount AS NVARCHAR) + 'A') AS aCountStr |
De SQL parsed wel zonder problemen, alleen bij executen ervan krijg ik dan de fout "Invalid column name 'aCount'". Eenzelfde melding die ik zou krijgen als ik een IF statement zou gebruiken.
In pseudocode zou ik iig ongeveer de volgende stappen aanhouden:
count(aStatussen)
count(bStatussen)
count(cStatussen)
count(dStatussen)
count(eStatussen)
als aStatussen > 0 dan strStatus = aStatussen + 'A'
als strStatus <> '' dan strStatus += '/'
als bStatussen > 0 dan strStatus += bStatussen + 'B'
als strStatus <> '' dan strStatus += '/'
als cStatussen > 0 dan strStatus += cStatussen + 'C'
als strStatus <> '' dan strStatus += '/'
als dStatussen > 0 dan strStatus += dStatussen + 'D'
als strStatus <> '' dan strStatus += '/'
als eStatussen > 0 dan strStatus += eStatussen + 'E'
als Substring(strStatus, Length(strStatus) -1) == '/' dan strStatus = Substring(strStatus, 0, Length(strStatus) -1)
Ik begin langzaam te twijfelen óf dit wel in SQL mogelijk is, in C# is het achteraf gezien op de DataTable wel mogelijk, maar ik zou het mooi vinden als ik vanuit SQL gewoon in 1x een correcte returnwaarde krijg.
Mijn vraag aan de rest van jullie Tweakers is dan nu ook of hetgene wat ik wil wel mogelijk is met SQL? En of iemand me dan ook kan helpen hiermee? Want zelf zit ik dus gigantisch vast hier.
Ja, het is een lange topicstart, maar ik hoop wel zo alles heel duidelijk te hebben weergegeven
Wanna play?