简体   繁体   中英

Using Sub-query result in where condition

I'm having an issue with a potentially simple query I can't get working. I'm also not entirely sure on how to Google it. So here it goes.

I have 2 tables:

  • TableA - Holds the main records I need to return
  • TableB - Holds many records per record in TableA

All I need to do is return records from TableA that match a query such as:

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

but with this extra bit on the end (I know the query is wrong, but hopefully it gives you a clure as to what I'm after (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;

So essentially I want to return all records from TableA as long as they have a status of 2 in TableA, and the earliest record in TableB is at least 15 minutes old, and has a status value less than 5.

Hopefully I have explained it in a way you can understand what I'm trying to accomplish.

Use CROSS APPLY to simulate a join and get only the first match:

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;

I think apply is a good approach, but the logic would seem to be:

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;

I would just turn your check around and use a 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM