подсчет нулевых значений в sql с помощью where и group by - PullRequest
4 голосов
/ 26 марта 2012

Вот пример данных для тестовой таблицы, которую я имею

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

Теперь для всех parentIds (включая те, которые имеют NULL) я хочу подсчитать все существующие childIds

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

Результат, который я получаю:

parentId    nbr
NULL        2
11          1

Одинаковое число (nbr), которое я получаю как для подарка = 1, так и для подарка = 0.Кажется, я не могу навязать условие для сгруппированного значения NULL.
В чем заключается ошибка, которую я совершаю, и каково решение для запроса, который я хочу сделать?


ОБНОВЛЕНИЕ :

Поскольку приведенный мною контрольный пример не является репрезентативным, пока я лучше не воссоздаю реальную ситуацию, я попытаюсь объяснить возникшую проблему.

Я создал представление с полным внешним соединением, поэтому у меня есть несколько записей, имеющих NULL для childId и некоторые записи, имеющие NULL для parentId.
Теперь я хочу перечислить все значения parentIdNULL и не NULL) и для каждой из них подсчитайте все записи, которые, например, имеют present=1.Если я использую условие where present=1, оно исключает значения NULL из набора результатов, т.е. у меня не будет записи результата NULL|x для parentId|nbr.
Я решил это с помощью union all.В первом выборе у меня есть where present=1, а во втором выборе у меня 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

В результате я получаю

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

Единственная проблема с этим (кроме дублированной записи для parentId=NULL) заключается в том, что если нет записей с parentId=NULL иpresent=1, в результате у меня не будет записи с NULL | 0 для parentId|nbr, и я хочу перечислить ВСЕ родительские идентификаторы, как NULL, так и не NULL.
Так что для подведения итогов мне нужно иметьэтот формат вывода для present=1

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

и этот для present=0

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

Любая помощь?

Ответы [ 4 ]

2 голосов
/ 27 марта 2012

Используйте SUM-агрегацию текущего поля, приведя битовое поле к целому, как показано ниже:

SELECT parentId, SUM(CAST(present AS INTEGER)) as nbr
FROM TestTable
GROUP BY parentId
2 голосов
/ 26 марта 2012
where present=1 or parentId is NULL

Это было бы так. Либо у вас есть Present = 1, либо parentID имеет значение null. Нет оговорок о том, что parentID должен быть нулевым , а присутствует должно быть 1.

Что именно вы пытаетесь достичь?

Чтобы получить список всех ненулевых parentID, которые имеют значение = 1, и всех нулевых parentID, независимо от присутствия, вы можете использовать предложение where, но измените свою группу на GROUP BY parentid, present. Таким образом, вы покажете все ненулевые значения с настоящим 1 и все нулевые значения, оба с 0 и 1.

UPDATE: Исходя из ваших новых требований, вам также необходимо сгруппировать несуществующие комбинации. Нигде в вашем наборе данных нет значения NULL, 1, поэтому ваш обычный взгляд на него не будет иметь большого смысла. Вам нужно отделить парентиду и подарок от друг друга.

Один из способов сделать это - просто сделать следующее:

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

Это основано на тестировании с использованием sqlfiddle и вашего образца данных. http://sqlfiddle.com/#!3/8d7f6/29

0 голосов
/ 26 марта 2012

Попробуйте приведенный ниже фрагмент кода.

SELECT ParentId, COUNT(ChildId) nbr FROM SO

Где (Представлено = 1) ИЛИ (ParentId НЕДОСТУПЕН и присутствует = 1) Группировать по ParentId

- ИЛИ Вы можете попробовать нижеупомянутый код также.

SELECT ParentId, COUNT(ChildId) nbr FROM SO

Где присутствует = 1 группа по ParentId

0 голосов
/ 26 марта 2012

Если это результат, который вы ищете:

pId    nbr
NULL   1
10     0
11     1

Тогда я думаю, что это SQL, который вы ищете (еще не тестировался, сервер недоступен):

select distinct 
  parentId as pId, 
  (select count(*) from TestTable where parentId=pId and present=1) as nbr
from TestTable 
group by parentId
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...