TSQL определяет, все ли записи в группе имеют одинаковое значение

#sql-server #tsql

#sql-server #tsql

Вопрос:

У меня есть таблица, содержащая поле, которое используется для группировки, и другое поле, в котором хранятся данные. Мне нужен хороший способ найти любое значение GroupColumn, где каждое значение DataColumn содержит определенное значение.

Пример

  ------------- ------------ 
| GroupColumn | DataColumn |
 ------------- ------------ 
| GroupA      | Data1      |
| GroupA      | Data2      |
| GroupA      | Data3      |
| GroupB      | Data1      |<---These two values are the same
| GroupB      | Data1      |<---for the same group
| GroupC      | Data1      |
| GroupC      | Data2      |
| GroupC      | Data2      |
| GroupC      | Data3      |
 ------------- ------------ 
  

Желаемый результат

Группа B

В приведенном выше примере столбец данных изменяется для GroupA и groupC, но для GroupB оба значения в столбце данных одинаковы, поэтому я бы хотел, чтобы этот результат был возвращен.

Текущее решение

У меня есть 2 текущих решения, основанных на одной и той же теме, но я чувствую, что это то, что SQL должен уметь делать проще.

  1. Сгруппируйте все в таблице, посчитайте, сколько раз появляется GroupColumn, и поместите это в таблицу. Сделайте то же самое, но примените условие. Соедините 2 таблицы и посмотрите, где 2 значения не совпадают.

     SELECT GROUPCOLUMN, COUNT(*) [TOTAL] INTO #ALL
    FROM #TABLE
    GROUP BY GROUPCOLUMN
    
    SELECT GROUPCOLUMN, COUNT(*) [TOTAL] INTO #SOME
    FROM #TABLE
    WHERE DATACOLUMN = 'DATA1'
    GROUP BY GROUPCOLUMN
    
    SELECT * FROM #ALL A
    INNER JOIN #SOME S ON A.GROUPCOLUMN = S.GROUPCOLUMN
    WHERE S.TOTAL = A.TOTAL
      
  2. Используйте СУММУ и РЕГИСТР для проверки конкретного значения, подсчитайте все и проверьте в подзапросе.

     SELECT * FROM 
    (SELECT GROUPCOLUMN, SUM(CASE WHEN DATACOLUMN = 'DATA1' THEN 1 ELSE 0 END) [VALUE], COUNT(*) [TOTAL] FROM #TABLE (NOLOCK)
    GROUP BY GROUPCOLUMN) A
    WHERE A.VALUE = A.TOTAL
      

Есть ли лучший способ сделать это в SQL?

Заранее спасибо.

Ниндзя

Ответ №1:

Вы ищете HAVING пункт

 SELECT GROUPCOLUMN
FROM   #TABLE (NOLOCK)
GROUP  BY GROUPCOLUMN
HAVING Count(*) = Count(case when DATACOLUMN = 'DATA1' then 1 end) 
  

Комментарии:

1. Так просто и в то же время так эффективно! Большое спасибо @prdp.

Ответ №2:

Похоже, вы ищете каждую группу, которая имеет одно отдельное значение в DATACOLUMN :

 SELECT GROUPCOLUMN
FROM #TABLE
GROUP BY GROUPCOLUMN
HAVING COUNT(DISTINCT DATACOLUMN) = 1
  

Обратите внимание, что COUNT(DISTINCT ...) это не NULL считается отдельным значением.

Комментарии:

1. Ага! Именно то, что я искал. Я забыл о старом добром COUNT(DISTINCT ...)

Ответ №3:

Для этого вы должны иметь возможность сравнивать COUNT(*) с. COUNT(DISTINCT DATACOLUMN) Вот так:

 SELECT GROUPCOLUMN
FROM #TABLE
GROUP BY GROUPCOLUMN
HAVING Count(*) = Count(DISTINCT DATACOLUMN)
  

Комментарии:

1. Но он проверяет только для 'DATA1'

2. в примере sql используется это значение, но в тексте вопроса указано только «определенное значение». Не будучи уверенным в требовании, я бы, конечно, предпочел более гибкое и обобщенное решение.