Zählen von Nullwerten in sql mit where und group by-Klausel

Hier sind die Beispieldaten für Testtabelle, die ich habe

[childId] [parentId] [present] 1 10 0 2 11 1 3 NULL 0 4 NULL 0 NULL 10 0 

Nun, für alle Eltern (einschließlich der mit NULL) möchte ich alle gegenwärtigen Kinder zählen

 select parentId, count(childId) as nbr from TestTable where present=1 or parentId is NULL group by parentId 

Das Ergebnis, das ich bekomme, ist

 parentId nbr NULL 2 11 1 

Gleiche nbr ( nbr ) bekomme ich für beide vorhanden = 1 und vorhanden = 0. Es scheint, dass ich keine Bedingung für den NULL gruppierten Wert auferlegen kann.
Was ist der Fehler, den ich mache und was ist die Lösung für die Abfrage, die ich machen möchte?


UPDATE :

Da der Testfall, den ich gab, nicht repräsentativ ist, bis ich die reale Situation besser umschaue, werde ich versuchen, das Problem zu erklären, mit dem ich konfrontiert bin.

Ich habe eine view mit voller äußerer Verknüpfung erstellt, also habe ich einige Aufzeichnungen mit NULL für childId und einige datasätze mit NULL für parentId .
Nun möchte ich alle parentId Werte (beide NULL und non NULL ) parentId und für jeden von ihnen zählen alle datasätze, die zum Beispiel present=1 . Wenn ich die where present=1 Bedingung verwende, eliminiert sie NULL-Werte aus der Ergebnismenge, dh ich habe keine Ergebnisdatensätze NULL|x für parentId|nbr .
Ich habe das mit der union all getriggers. In der ersten Auswahl habe ich, where present=1 und in der zweiten Auswahl habe ich, where present=1 and parentId is NULL .

 select parentId, count(childId) as nbr from TestTable where present=0 group by parentId union all select parentId, count(childId) as nbr from TestTable where present=0 and parentId is NULL group by parentId 

Das Ergebnis, das ich bekomme, ist

  [parentId] [nbr] NULL 2 10 1 NULL 2 

Das einzige Problem mit diesem (neben doppelten datasatz für parentId=NULL ), ist, dass, wenn es keine datasätze mit parentId=NULL und present=1 , im Ergebnis habe ich keinen datasatz mit NULL | 0 NULL | 0 für parentId|nbr und ich möchte alle parentIds, beide NULL und nicht NULL auflisten.
Um es zusammenzufassen, muss ich dieses Format der Ausgabe für present=1

  [parentId] [nbr] NULL 0 10 0 11 1 

und diese für present=0

  [parentId] [nbr] NULL 2 10 2 11 0 

Irgendeine Hilfe?

 where present=1 or parentId is NULL 

Das wäre es Entweder hast du Present = 1 oder parentID ist null. Es gibt keine Klausel sagen, dass parentID sollte null und präsentieren sollte 1 sein.

Was genau versuchst du zu erreichen?

Um alle Nicht-Null-ParentID aufzurufen, die vorhanden ist = 1 und alle Null-ParentID unabhängig von der Gegenwart, können Sie Ihre where-Klausel verwenden, aber bearbeiten Sie Ihre Gruppe von GROUP BY parentid, present . Auf diese Weise zeigen Sie alle Nicht-Null mit Gegenwart 1, und alle Null, beide vorhanden 0 und 1.

UPDATE: Basierend auf Ihren neuen Anforderungen müssen Sie auch für nicht vorhandene Kombinationen gruppieren. Nirgendwo in deinem Dataset gibt es einen NULL, 1 Wert – also deine gewöhnliche Art, es zu betrachten, wird nicht viel Sinn machen. Sie müssen das Parentid trennen und von einander präsentieren.

Eine Möglichkeit, dies zu tun, ist einfach:

 SELECT parentID, Pres1.nbr_pres_1, Pres0.nbr_pres_0 FROM t OUTER APPLY (SELECT COUNT(1) as nbr_pres_1 FROM t t1 WHERE coalesce( t.parentid , -999) = coalesce(t1.parentid ,-999) and present=1 ) Pres1 OUTER APPLY (SELECT COUNT(1) as nbr_pres_0 FROM t t0 WHERE coalesce( t.parentid , -999) = coalesce(t0.parentid ,-999) and present=0 ) Pres0 GROUP BY t.ParentID, Pres1.nbr_pres_1, Pres0.nbr_pres_0 

Dies basiert auf dem Testen mit sqlfiddle und Ihrem Beispieldatensatz. http://sqlfiddle.com/#!3/8d7f6/29

Verwenden Sie eine SUM-Aggregation des aktuellen Feldes und casting Sie das Bit-Feld in die Ganzzahl wie folgt:

 SELECT parentId, SUM(CAST(present AS INTEGER)) as nbr FROM TestTable GROUP BY parentId 

Wenn dies der Ergebnis ist, suchen Sie:

 pId nbr NULL 1 10 0 11 1 

Dann denke ich, das ist der Sql, den du suchst (noch nicht getestet, kein server vorhanden):

 select distinct parentId as pId, (select count(*) from TestTable where parentId=pId and present=1) as nbr from TestTable group by parentId 

Testen Sie unten erwähnten Code-Snippet.

 SELECT ParentId, COUNT(ChildId) nbr FROM SO 

Wo (Gegenwart = 1) ODER (ParentId IS NULL AND Present = 1) Group by ParentId

– Sie können den unten genannten Code auch ausprobieren.

 SELECT ParentId, COUNT(ChildId) nbr FROM SO 

Wo Gegenwart = 1 Gruppe durch ParentId