Выделить отдельные ненулевые строки SQL Server 2005 - PullRequest
0 голосов
/ 04 декабря 2010

Я столкнулся со следующей проблемой.
У меня есть такая таблица:

ID   ID1     ID2     ID3     ID4     ID5
1   NULL    NULL    NULL    NULL    1
2   NULL    NULL    NULL    2       NULL
3   NULL    NULL    NULL    2       1
4   3       NULL    NULL    2       NULL
5   3       NULL    NULL    2       1
6   NULL    5       NULL    2       NULL

И мне нужно получить отдельные строки, которые называются NULL равными любому значению.Для этого примера ответом является:

ID   ID1     ID2     ID3     ID4     ID5
5   3       NULL    NULL    2       1
6   NULL    5       NULL    2       NULL

PS Здесь ID является первичным ключом, следовательно, уникальным.ID1-ID5 - любые целые числа.
Заранее спасибо! ОБНОВЛЕНО
Сказать, что ноль равен любому числу, я имею в виду, что он поглощен любым числом.

Ответы [ 3 ]

4 голосов
/ 04 декабря 2010

Это работает, не знаю, можно ли это сделать проще

SELECT ID1, ID2, ID3, ID4, ID5
FROM IDS OUTT
WHERE NOT EXISTS (SELECT 1
                FROM IDS INN
                WHERE OUTT.ID != INN.ID AND
                      (ISNULL(OUTT.ID1, INN.ID1) = INN.ID1 OR (INN.ID1 IS NULL AND OUTT.ID1 IS NULL)) AND
                      (ISNULL(OUTT.ID2, INN.ID2) = INN.ID2 OR (INN.ID2 IS NULL AND OUTT.ID2 IS NULL)) AND
                      (ISNULL(OUTT.ID3, INN.ID3) = INN.ID3 OR (INN.ID3 IS NULL AND OUTT.ID3 IS NULL)) AND
                      (ISNULL(OUTT.ID4, INN.ID4) = INN.ID4 OR (INN.ID4 IS NULL AND OUTT.ID4 IS NULL)) AND
                      (ISNULL(OUTT.ID5, INN.ID5) = INN.ID5 OR (INN.ID5 IS NULL AND OUTT.ID5 IS NULL)))

РЕДАКТИРОВАТЬ: Нашли более приятную альтернативу, если ваши идентификаторы никогда не имеют отрицательных чисел

SELECT ID1, ID2, ID3, ID4, ID5
FROM IDS OUTT
WHERE NOT EXISTS (SELECT 1
                FROM IDS INN
                WHERE OUTT.ID != INN.ID AND
                      coalesce(OUTT.ID1, INN.ID1,-1) = isnull(INN.ID1,-1) AND
                      coalesce(OUTT.ID2, INN.ID2,-1) = isnull(INN.ID2,-1) AND
                      coalesce(OUTT.ID3, INN.ID3,-1) = isnull(INN.ID3,-1) AND
                      coalesce(OUTT.ID4, INN.ID4,-1) = isnull(INN.ID4,-1) AND
                      coalesce(OUTT.ID5, INN.ID5,-1) = isnull(INN.ID5,-1))  

EDIT2: есть один случай, когда он не будет работать - в случае, если две строки (с разными идентификаторами) имеют одинаковую форму. Я предполагаю, что это не там. Если такая вещь присутствует, то сначала создайте представление с выбором, отличным от базовой таблицы, а затем примените этот запрос.

1 голос
/ 04 декабря 2010

Постановка вашей проблемы, насколько я понимаю:

Вы начинаете с полной таблицы:

ID   ID1     ID2     ID3     ID4     ID5
1   NULL    NULL    NULL    NULL    1
2   NULL    NULL    NULL    2       NULL
3   NULL    NULL    NULL    2       1
4   3       NULL    NULL    2       NULL
5   3       NULL    NULL    2       1
6   NULL    5       NULL    2       NULL

Затем вы устраняете «дублирующие» строки, т.е.строки, которые имеют меньше, но имеют те же значения, что и другие строки (кроме NULL - и столбец ID не включен):

  • Строка 1 исключается, поскольку строка 3 идентична, но имеет больше значений в местах, где строка 1 имеет NULL.

  • Строка 2 также удаляется (любой из) строк 2 или 4.

  • Строки 3 и 4 исключаются строкой 5.

Затем у вас остаются строки 5 и 6:

ID   ID1     ID2     ID3     ID4     ID5
5   3       NULL    NULL    2       1
6   NULL    5       NULL    2       NULL

Мой ответ:

Честно говоря, я не понимаю, как это можно сделать с помощью SELECT DISTINCT SQL или, в более общем смысле, с помощью логики SQL на основе множеств.Я мог бы предположить, что вы могли бы выполнить такую ​​фильтрацию с более процедурным подходом (например, с помощью курсоров) - но я не могу предоставить решение для этого.


Примечаниео терминологии:

NULL равно любому значению

NULL никогда равно любому значению, поскольку NULL сам по себене ценность;это отсутствие значения.NULL по существу означает «неизвестный».(Тот факт, что NULL не является значением, является причиной того, что вы не должны писать IDx = NULL, а вместо этого IDx IS NULL.)

0 голосов
/ 04 декабря 2010

Если ID1, ID2 (...) имеет всегда одинаковое значение, как в вашем примере, вы можете сделать это

Select 
 SUM(id1)/COUNT(id1),
 SUM(id2)/COUNT(id2),
 SUM(id3)/COUNT(id3),
 SUM(id4)/COUNT(id4),
 SUM(id5)/COUNT(id5)  From TABLE

Функции SUM и COUNT будут игнорировать эти нулевые значения.Но все же немного смутил ваш вопрос .. :)

...