Как эффективно сопоставить даты в SQL Server? - PullRequest
0 голосов
/ 18 марта 2019

Я пытаюсь вернуть первую регистрацию для человека на основании минимальной даты регистрации, а затем вернуть полную информацию.Данные выглядят примерно так:

Warehouse_ID  SourceID  firstName  lastName  firstProgramSource  firstProgramName  firstProgramCreatedDate  totalPaid  totalRegistrations
12345         1         Max        Smith     League              Kid Hockey        2017-06-06               $100       3
12345         6         Max        Smith     Activity            Figure Skating    2018-09-26               $35        1

Конечная цель - вернуть одну строку на человека, которая выглядит следующим образом:

Warehouse_ID  SourceID  firstName  lastName  firstProgramSource  firstProgramName  firstProgramCreatedDate  totalPaid  totalRegistrations
12345         1         Max        Smith     League              Kid Hockey        2017-06-06               $135       4

Итак, это агрегирует переменные totalPaid и totalRegistrationsоснованный на Warehouse_ID и извлечет остальную информацию на основе min (firstProgramCreatedDate), специфичного для Warehouse_ID.

Это закончится в Таблице, поэтому то, что я недавно попробовал, игнорирует агрегирование totalPaid и totalRegistrations длясейчас (я могу получить это в другом запросе довольно легко).Кажется, что используемый мной запрос работает, но он выполняется вечно;Кажется, что он будет проходить построчно для> 50 000 строк, что занимает вечность.

select M.*
from (
select Warehouse_ID, min(FirstProgramCreatedDate) First
from vw_FirstRegistration
group by Warehouse_ID
) B
left join vw_FirstRegistration M on B.Warehouse_ID = M.Warehouse_ID
where B.First in (M.FirstProgramCreatedDate)
order by B.Warehouse_ID

Любой совет, как мне достичь своей цели без выполнения этого запроса в течение часа плюс?

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Комбинация оконной функции ROW_NUMBER плюс предложение OVER в выражении SUM должны работать очень хорошо.

Вот запрос:

SELECT TOP (1) WITH TIES
  v.Warehouse_ID
  ,v.SourceID
  ,v.firstName
  ,v.lastName
  ,v.firstProgramSource
  ,v.firstProgramName
  ,v.firstProgramCreatedDate
  ,SUM(v.totalPaid) OVER (PARTITION BY v.Warehouse_ID) AS totalPaid
  ,SUM(v.totalRegistrations) OVER (PARTITION BY v.Warehouse_ID) AS totalRegistrations
FROM
  @vw_FirstRegistration AS v
ORDER BY
  ROW_NUMBER() OVER (PARTITION BY v.Warehouse_ID 
    ORDER BY CASE WHEN v.firstProgramCreatedDate IS NULL THEN 1 ELSE 0 END,
             v.firstProgramCreatedDate)

А вот демоверсия Rextester: https://rextester.com/GNOB14793

Результаты (я добавил еще одного ребенка ...):

+--------------+----------+-----------+----------+--------------------+------------------+-------------------------+-----------+--------------------+
| Warehouse_ID | SourceID | firstName | lastName | firstProgramSource | firstProgramName | firstProgramCreatedDate | totalPaid | totalRegistrations |
+--------------+----------+-----------+----------+--------------------+------------------+-------------------------+-----------+--------------------+
|        12345 |        1 | Max       | Smith    | League             | Kid Hockey       | 2017-06-06              |    135.00 |                  4 |
|        12346 |        6 | Joe       | Jones    | Activity           | Other Activity   | 2017-09-26              |    125.00 |                  4 |
+--------------+----------+-----------+----------+--------------------+------------------+-------------------------+-----------+--------------------+

РЕДАКТИРОВАТЬ: Изменено ORDER BY на основе комментариев.

0 голосов
/ 18 марта 2019

Попробуйте использовать ROW_NUMBER () с PARTITIYION BY.

Для получения дополнительной информации, пожалуйста, обратитесь к: https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql?view=sql-server-2017

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...