0

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.

2
  • can you show some sample data and the expected output? Commented Oct 14, 2018 at 21:59
  • Please read this for some tips on improving your question. Commented Oct 15, 2018 at 0:55

3 Answers 3

1

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;
Sign up to request clarification or add additional context in comments.

Comments

0

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;

2 Comments

This wouldn't return a row if there are two B records that fit in the 15 minute window and the earlier one has a status >= 5 and the other is < 5. I guess it depends on his needs exactly, but the way I read the question is how I wrote my answer.
Oof, I just noticed your date filter is correct and mine was wrong :)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.