SQL - объединение двух таблиц на основе актуальных записей - PullRequest
0 голосов
/ 14 марта 2019

У меня есть две таблицы

1- Таблица тестовых модулей

TestModules

enter image description here

2- Таблица TestModule_Results

TestModule_Results

enter image description here

Чтобы получить необходимую информацию для каждого TestModule, я использую FULL OUTER JOIN, и он работает нормально.

Результат FULL OUTER JOIN

enter image description here

Но то, что требуется, немного отличается. На приведенном выше рисунке показано, что TestModuleID = 5 указан дважды, и необходимо перечислить «актуальные» результаты, основанные на времени «ChangedAt»

Конечно, я могу сделать следующее:

SELECT TOP 1 * FROM TestModule_Results
WHERE DeviceID = 'xxx' and TestModuleID = 'yyy'
ORDER BY ChangedAt DESC

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

Ожидаемый результат должен быть следующим: ExpectedOutput

Любой совет, как я могу реализовать это в SP?

Ответы [ 2 ]

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

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

--NOTE: a Common Table Expression requires the previous command
--to be explicitly terminiated, prepending a ; covers that
;WITH cteTR as (
    SELECT * 
        , ROW_NUMBER() OVER (PARTITION BY DeviceID, TestModuleID 
            ORDER BY ChangedAt DESC) AS ResultOrder
    FROM TestModule_Results
    --cteTR is now just like TestModule_Results but has an 
    --additional field ResultOrder that is 1 for the newest, 
    --2 for the second newest, etc. for every unique (DeviceID,TestModuleID) pair
)
SELECT * 
FROM TestModules as M  --Use INNER JOIN to get only modules with results, 
  --or LEFT OUTER JOIN to include modules without any results yet
  INNER JOIN cteTR as R
    ON M.DeviceID = R.DeviceID AND M.TestModuleID = R.TestModuleID
WHERE R.ResultOrder = 1 
-- OR R.ResultOrder IS NULL --add if Left Outer Join
0 голосов
/ 14 марта 2019

Вы говорите "это решение для одной строки"? Отлично. Используйте CROSS APPLY и измените предложение WHERE с литерала ручного ввода на поля исходной таблицы. APPLY работает на уровне строк.

SELECT *
FROM TestModules t
CROSS APPLY
(
    SELECT TOP 1 * FROM TestModule_Results
    WHERE TestModule_Results.DeviceID = TestModules.DeviceID -- put the connecting fields here
    ORDER BY ChangedAt DESC
)tr
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...