Каков наиболее эффективный способ сопоставления подзапроса для большой таблицы в T-SQL? - PullRequest
0 голосов
/ 15 апреля 2019

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

Я пытался написать OUTER JOIN, но в таблице использования / записей слишком много данных, чтобы это работало эффективно,И я попытался написать CROSS APPLY, но я, должно быть, что-то напортачил, потому что это тоже не очень эффективно работает.

Пример файлов:

Мой базовый запрос:

Inv. Date      Mk      Model      Serial
2019-03-29     AA      420D       0FDP09999
2019-03-21     AA      A19B-SSL   0DX240481

Таблица использования / записей:

Mk      Serial      Usage      Units      Record Date
AA      0FDP09999   2345.0     H          2019-03-27
AA      0FDP09999   2349.2     H          2019-03-28
AA      0FDP09999   2351.8     H          2019-03-29
AA      0DX240481   0.0        H          2019-03-21
AA      0DX240481   24.0       H          2019-03-22

Выходные данные должны быть:

Inv. Date      Mk      Model      Serial      Usage      Units      Record Date
2019-03-29     AA      420D       0FDP09999   2351.8     H          2019-03-29
2019-03-21     AA      A19B-SSL   0DX240481   0.0        H          2019-03-21

... с возвратом использования, единиц и даты записиТОЛЬКО самая последняя запись до даты выставления счета.

Есть предложения?

Ответы [ 2 ]

1 голос
/ 16 апреля 2019

Вы можете попробовать левое соединение и row_number().

SELECT t1.[Inv. Date],
       t1.[Mk],
       t1.[Model],
       t1.[Serial],
       t2.[Usage],
       t2.[Units],
       t2.[Record Date]
       FROM (SELECT t1.[Inv. Date],
                    t1.[Mk],
                    t1.[Model],
                    t1.[Serial],
                    t2.[Usage],
                    t2.[Units],
                    t2.[Record Date],
                    row_number() OVER (PARTITION BY t1.[Inv. Date]
                                       ORDER BY t2.[Record Date] DESC) rn
                    FROM table1 t1
                         LEFT JOIN table2 t2
                                   ON t2.[Mk] = t1.[Mk]
                                      AND t2.[Serial] = t1.[Serial]
                                      AND t2.[Record Date] <= t1.[Inv. Date]) x
       WHERE x.rn = 1;

Для производительности попробуйте индекс по ([Mk], [Serial], [Inv. Date]) для первой и ([Mk], [Serial], [Record Date]) для второй таблицы. Или, возможно, попробуйте изменить положение [Mk] и [Serial], если сериалы более или менее "уникальны" также для разных марок.

0 голосов
/ 16 апреля 2019

Чтобы решить эту проблему, я создал дополнительные запросы вне того, что изначально было моим базовым запросом.

В первом внешнем запросе я сделал это («Номер счета» - это дополнительное поле, которое я вызывал, чтобыуникальная нумерация строк, в случае, если машина была продана один раз, выкуплена, а затем снова продана в течение определенного периода времени):

CASE
    WHEN Q1.[Usage] IS NULL
    THEN 1
    ELSE ROW_NUMBER() OVER (PARTITION BY Q1.[Serial Number], Q1.[Mk], Q1.[Invoice Number] ORDER BY Q1.[Record Date] DESC)
END AS [RowNum]

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

Затем следующий внешний запрос захватывает только строки с RowNum = 1.

...