Использование результата подзапроса в условии where - PullRequest
0 голосов
/ 15 октября 2018

У меня проблема с потенциально простым запросом, который я не могу получить.Я также не совсем уверен, как Google это.Итак, все.

У меня есть 2 таблицы:

  • TableA - Содержит основные записи, которые мне нужно вернуть
  • TableB - Содержит много записей на одну запись в TableA

Все, что мне нужно сделать, это вернуть записи из таблицы А, которые соответствуют запросу, например:

SELECT Description, Type, Status
FROM TableA
WHERE Status = 2;

, но с этим дополнительным битом в конце (я знаю, что запрос неверный, но, надеюсь, это даст вам представление о том, что мне нужно (PSEUDO CODE):

SELECT ID, Description, Type, Status
FROM TableA
JOIN TableB ON TableB.ID = TableA.ID
WHERE Status = 2
AND (MIN(TableB.StatusChanged) > DATEADD(minute, -15, GETDATE()))
AND TableB.Status < 5;

Поэтому, по сути, я хочу вернуть все записи из TableA, если они имеют статус 2 в TableAи самая ранняя запись в Таблице B имеет возраст не менее 15 минут и значение состояния меньше 5.

Надеюсь, я объяснил это так, чтобы вы могли понять, чего я пытаюсь достичь.

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Я думаю, apply - хороший подход, но логика выглядит так:

SELECT a.Description, a.Type, a.Status, b.*
FROM TableA a CROSS APPLY
     (SELECT TOP 1 *
      FROM TableB b
      WHERE a.ID = b.ID AND -- the join condition            
            b.StatusChanged < DATEADD(MINUTE, -15, GETDATE())
      ORDER BY b.StatusChanged -- the earliest one that matches
     ) b
WHERE a.Status = 2 AND b.Status < 5;
0 голосов
/ 15 октября 2018

Я бы просто перевернул ваш чек и использовал not exists

SELECT ID, Description, Type, Status
FROM TableA
JOIN TableB ON TableB.ID = TableA.ID
    AND TableB.Status < 5
    AND not exists (
        select * from TableB B2 where B2.ID=TableB.ID and B2.StatusChanged < DATEADD(minute, -15, GETDATE())
        )
WHERE TableA.Status = 2
0 голосов
/ 15 октября 2018

Используйте CROSS APPLY для имитации соединения и получения только первого совпадения:

SELECT a.Description, a.Type, a.Status, b.*
FROM TableA a
    CROSS APPLY (
        SELECT TOP 1 *
        FROM TableB b
        WHERE a.ID = b.ID -- the join condition
            AND b.Status < 5
            AND b.StatusChanged < DATEADD(MINUTE, -15, GETDATE()
        ORDER BY b.StatusChanged -- the earliest one that matches
    ) b
WHERE a.Status = 2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...