SQL Cross Apply с тремя таблицами

Я пытаюсь объединить 3 таблицы, используя Cross Apply, чтобы сэкономить время. Я могу получить желаемые результаты, но время работы слишком велико. Три таблицы:

-CUSTOMERS, который имеет столбцы CustomerId(первичный ключ) и CurrentSetType

-HISTORY, который имеет столбцы CustomerId(внешний ключ), SetType и TimeStamp

-UPDATELIST, в котором есть столбец CustomerId

Моя цель — найти самые последние SetType из HISTORY для каждого CustomerId в UPDATELIST, который отличается от CurrentSetType (это часть прославленной кнопки «отменить»). Я считаю, что моя проблема заключается в том, что таблицы CUSTOMERS и HISTORY огромны, и я не думаю, что сопоставлю их в пары с меньшей UPDATELIST, прежде чем выполнять перекрестное применение ко всему этому. Мой текущий запрос таков:

DECLARE @UPDATELIST TABLE (Identifier INT NOT NULL PRIMARY KEY);
INSERT INTO @UPDATELIST (Identifier) VALUES (#####); -- a few hundred lines of this

SELECT CustomerId, ITEM.SetType
FROM CUSTOMERS
CROSS APPLY
 (SELECT TOP 1 SetType FROM HISTORY
  WHERE HISTORY.CustomerId IN (SELECT Identifier FROM @UPDATELIST)
  AND HISTORY.CustomerId = CUSTOMERS.CustomerId
  AND HISTORY.SetType != CUSTOMERS.CurrentSetType ORDER BY TimeStamp DESC) AS ITEM

Какой самый эффективный запрос для этого?

РЕДАКТИРОВАТЬ: я использую MSDN SQL версии 12.0.5532.


person TS-    schedule 23.04.2018    source источник
comment
Какой SQL вы используете? Майкрософт, MySQL? Какая версия?   -  person GSazheniuk    schedule 24.04.2018
comment
Какие rdbms вы используете? Пожалуйста, отредактируйте свой вопрос, чтобы включить соответствующие rdbms (тег продукта и версии)   -  person Zohar Peled    schedule 24.04.2018
comment
Что такое MSDN SQL??? Это SQL Server. Так что добавьте тег к вашему вопросу. Научитесь правильно ставить теги.   -  person Eric    schedule 24.04.2018


Ответы (1)


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

SELECT
    CustomerID
    , SetType
FROM
    (
        SELECT
            C.CustomerID
            , H.SetType
            , ROW_NUMBER() OVER (PARTITION BY C.CustomerID ORDER BY H.TimeStamp DESC) R
        FROM
            CUSTOMERS C
            JOIN UPDATELIST U ON U.CustomerId = C.CustomerId
            JOIN HISTORY H ON
                H.CustomerId = C.CustomerId
                AND H.SetType <> C.CurrentSetType
    ) Q
WHERE R = 1

Как это работает?

person Chris Mack    schedule 23.04.2018
comment
Меньше секунды! Использование «ROW_NUMBER()» было отличной идеей, оно позволяет вообще не использовать «TOP» - person TS-; 24.04.2018