T-SQL — поиск строк со значением одного столбца, которые связаны с несколькими вхождениями значений другого столбца

#tsql #search #group-by #query-optimization #sql-server-2014

#tsql #Поиск #группировка по #оптимизация запросов #sql-server-2014

Вопрос:

T-SQL — поиск строк со значением одного столбца, которые связаны с несколькими вхождениями значений другого столбца.

Цель состоит в том, чтобы найти вхождения значений table1.col1, которые имеют несколько значений для table1.col2. (ПРИМЕЧАНИЕ: значение в любой таблице не является фиксированным, например, мы не ищем шаблон, такой как «ABC», но должно быть определенным значением.)

( Group by будет найдено пары (col1, col2) кортежей, которые являются одинаковыми. )

На самом деле у меня есть некоторый код, который я считаю теоретически правильным, но работает очень, очень медленно в моей системе:

 -- find examples where the 1st-column value exists on more than one second-column value to test this. 

Select TOP 10 [Col_1], count(1) as countRows_outer from
(
    SELECT [Col_2]
          ,[Col_1]
          ,count(1) as countRowsInner

      FROM [OurDatabase].[dbo].[OurTable]
      WHERE 
      (
        (Col_1 is not null)
        and
        (len (Col_1) > 0)
      )
      group by [Col_2] ,[Col_1] -- after studying:  Inner group by *NOT* needed
      having (count(1) >= 2) -- not really needed, but limits search set, faster query results
        --order by  [Col_1],  [Col_2] -- , countRows desc
)c1
group by Col_1
having(count(1)  >= 2) -- > 1 (per answer below, may be more efficient here)
order by countRows_outer desc
  

В приведенном выше коде внутреннее предложение ‘having’ на самом деле не требуется, равно как и «верхние» ключевые слова, но они немного ускоряют процесс.

У кого-нибудь есть лучший способ или, альтернативно, способ ускорить это.

В этом примере все столбцы имеют nvarchar(255).

Я использую SSMS 14.017 с базовой базой данных SQL select @@version = Microsoft SQL Server 2014 (SP3)

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

1. Не уверен, почему здесь есть понижающий голос?

Ответ №1:

Разве вы не можете сделать это с помощью простой ГРУППЫ ПО

 SELECT col1
FROM 
    table
GROUP BY col1
HAVING COUNT(DISTINCT col2)> 1
  

Это должно привести к появлению значений table1.col1, которые имеют несколько значений для table1.col2

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

1. Внутренняя «группа по» в моем запросе сверху не нужна и будет учитывать только пары (col1, col2), следовательно, она получает разные результаты. Я думаю, что ответ — лучший запрос, и работает правильно и быстрее. Вероятно, «> 1» по крайней мере так же быстро, как «> = 2», в зависимости от базового оптимизатора и даже скомпилированного машинного кода, так что хорошая работа.

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