Предложение GROUP BY рассматривает все поля VARCHAR как разные

Я стал свидетелем странного поведения при попытке GROUP BY поля VARCHAR.

Возьмем следующий пример, где я пытаюсь определить клиентов, которые хотя бы раз меняли имя в прошлом.

CREATE TABLE #CustomersHistory
(
Id INT IDENTITY(1,1),
CustomerId INT,
Name VARCHAR(200)
)

INSERT INTO #CustomersHistory VALUES (12, 'AAA')
INSERT INTO #CustomersHistory VALUES (12, 'AAA')
INSERT INTO #CustomersHistory VALUES (12, 'BBB')
INSERT INTO #CustomersHistory VALUES (44, '444')

SELECT ch.CustomerId, count(ch.Name) AS cnt
  FROM #CustomersHistory ch
  GROUP BY ch.CustomerId  HAVING  count(ch.Name) != 1

Что странно получается (как если бы «ААА» из первого INSERT отличалось от второго)

CustomerId  cnt  //  (I was expecting)
12          3    //   2
44          1    //   1
  • Является ли это поведение характерным для T-SQL?
  • Почему он ведет себя таким довольно нелогичным образом?
  • Как принято преодолевать это ограничение?

Примечание. Этот вопрос очень похож на проблему GROUP BY с varchar, где я не нашел ответа на вопрос Почему

Примечание: рекомендуется ли использовать HAVING count(ch.Name) != 1 вместо HAVING count(ch.Name) > 1?


person PPC    schedule 04.02.2013    source источник
comment
Чтобы прокомментировать › 1 vs != 1, во многих случаях (хотя и не обязательно в вашем случае) count() может быть 0 (например, нули игнорируются), но 0 != 1 и, следовательно, возможность некоторых неожиданных поведение. Это просто моя привычка.   -  person Code Magician    schedule 04.02.2013
comment
Я проведу собственное исследование по этому поводу и, возможно, задам новый вопрос. Спасибо еще раз   -  person PPC    schedule 04.02.2013


Ответы (1)


Оператор COUNT() будет считать все строки независимо от значения. Я думаю, вы можете использовать COUNT(DISTINCT ch.Name), который будет учитывать только уникальные имена.

SELECT ch.CustomerId, count(DISTINCT ch.Name) AS cnt
  FROM #CustomersHistory ch
  GROUP BY ch.CustomerId  HAVING  count(DISTINCT ch.Name) > 1

Дополнительные сведения см. в COUNT() статье о книге онлайн

person Code Magician    schedule 04.02.2013
comment
Рад, что смог помочь, Спасибо! - person Code Magician; 04.02.2013