Следует ли использовать объединения или подзапросы для сравнения значений в одной таблице? - PullRequest
0 голосов
/ 04 октября 2019

У меня есть следующий сценарий, в котором я пытаюсь сравнить даты похожих данных в одной и той же таблице, но строки имеют разные категории. Как мне написать SQL-запрос для этого? (с использованием SQL Server, SSMS)

В частности, у меня есть детали контракта, которые состоят из продуктов и конечных пользователей. Каждая из этих строк имеет дату. Для каждого контракта # я хочу сравнить даты начала и окончания продуктов и конечных пользователей. И я хочу исключить некоторые строки, если дата начала дистрибьютора>, чем дата окончания продукта.

Вот пример таблицы:

Пример таблицы

Contract    Type     TypeCode   Begin Date  End Date
11111       Product  12345      1/1/2019    12/31/2019
11111       Product  67890      8/1/2019    12/31/2020
11111       EndUser  AAA        1/1/2018    12/31/2019
11111       EndUser  BBB        1/1/2020    12/31/2020
22222       Product  12345      1/1/2019    12/31/2019
22222       Product  67890      1/1/2019    12/31/2019
22222       EndUser  AAA        8/1/2019    12/31/2020
22222       EndUser  BBB        1/1/2019    12/31/2019

Глядя на строку 4, дата начала для конечного пользователя наступает после даты окончания строки 1. Поэтому строку 1 следует исключить из результатов. Строки 1 и 2 следует сравнивать со строками 3 и 4, поскольку они находятся в одном контракте, а продукты должны сравниваться с конечным пользователем.

Обратите внимание, что в этой единой таблице будут сотни контрактов, продуктов и конечных пользователей. И повторюсь, я хочу сравнивать продукты и конечных пользователей только в том случае, если у них одинаковый номер договора.

Ответы [ 2 ]

0 голосов
/ 04 октября 2019

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

Я думаю, что оконные функции добиваются цели:

select t.*
from (select t.*,
             min(case when t.type = 'EndUser' then t.start end) over (partition by t.contract) as min_user_start
      from t
     ) t
where t.type = 'EndUser' or
      t.enddate < min_user_start;
0 голосов
/ 04 октября 2019

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

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

...