How to join table A to B to find all the entries in A whose intervals contain entries in B?

StackOverflow https://stackoverflow.com/questions/23417261

  •  13-07-2023
  •  | 
  •  

Domanda

I am comparing two tables A and B of log entry intervals, i.e. each record in a table is the first log entry and then another, for a given user, like this:

+--------+----------+--------+-----------+--------+
| userID |  date1   | logID1 |   date2   | logID2 |
+--------+----------+--------+-----------+--------+
|    235 | 1/3/2013 |     45 | 1/7/2013  |     48 |
|    235 | 4/6/2013 |     64 | 4/12/2013 |     73 |
|    462 | 1/4/2013 |     40 | 1/16/2013 |     50 |
+--------+----------+--------+-----------+--------+

I want to build a join query that links every record in A to all the records in B based on userID, where A contains B in either dates:

a.date1<=b.date1, a.date2>=b.date2

or IDs:

a.logID1<=b.logID1, a.logID2>=b.logID2

I want to return all records in A, regardless of whether or not there is a contained interval in B.

At first glance it seems like this would work:

select * from a
left join b
on
a.userID=b.userID
where
(a.date1<=b.date1 or a.logID1<=b.logID1)
and
(a.date2>=b.date2 or a.logID2>=b.logID2)
or
b.userID is null

But the problem is that if there is a record in A that has a matching userID in B but the A record does not contain the B record, the join will occur but the record will be filtered out by the WHERE condition, so the A record will not appear in the results.

If I try to resolve this by moving the WHERE conditions to the JOIN clause as follows:

select * from a
left join b
on
a.userID=b.userID
and
(a.date1<=b.date1 or a.logID1<=b.logID1)
and
(a.date2>=b.date2 or a.logID2>=b.logID2)

then I get this error message:

JOIN expression not supported.

I assume this means Access can't have nested OR conditions in the JOIN criteria.

What can I do to return a list of A, joined to their contained B where applicable?

È stato utile?

Soluzione

If you want all records in a, then put the condition in the on clause. where has strange effects. So try:

select *
from a left join
     b
     on a.userID = b.userID and
        (a.date1<=b.date1 or a.logID1<=b.logID1)
        (a.date2>=b.date2 or a.logID2>=b.logID2);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top