I am having a devil of a time on this one. I have been reading and trying different solutions but none are working for me. I have created a raffle system, and need to select users, who meet all conditions, that have not been previously selected before based on the same conditions.
TableA fields, user has checked in to location:
chID | ceID | cID | crID | clID | user_ID | chTime | chDate
1 1135 1001 1001 1163 8213451 17:21:30 2022-04-21
2 1135 1001 1001 1163 8213452 17:22:30 2022-04-21
3 1135 1001 1001 1163 8213453 17:23:30 2022-04-21
4 1135 1001 1001 1163 8213454 17:24:30 2022-04-21
5 1135 1001 1001 1163 8213455 17:25:30 2022-04-21
6 1155 1021 1001 1183 9213451 17:21:30 2022-04-21
7 1155 1021 1001 1183 9213452 17:22:30 2022-04-21
8 1155 1021 1001 1183 9213453 17:23:30 2022-04-21
9 1155 1021 1001 1183 9213454 17:24:30 2022-04-21
10 1155 1021 1001 1183 9213455 17:25:30 2022-04-21
11 1136 1002 1001 2163 8213451 17:21:30 2022-04-21
12 1136 1002 1001 2163 8213452 17:22:30 2022-04-21
13 1136 1002 1001 2163 8213453 17:23:30 2022-04-21
14 1136 1002 1001 2163 8213454 17:24:30 2022-04-21
15 1136 1002 1001 2163 8213455 17:25:30 2022-04-21
NOTE: 1-5 & 11-15 are same users, but group category IDs are different between them
TableB fields, user was previously selected as a winner:
bID | ceID | cID | crID | clID | user_ID | chTime | chDate
1 1135 1001 1001 1163 8213451 17:21:30 2022-04-21
2 1155 1021 1001 1183 9213454 17:24:30 2022-04-21
3 1136 1002 1001 2163 8213453 17:23:30 2022-04-21
Table A stores users that have checked into specific groups. Table B stores the user when a user from that group is selected for a raffle.
I need to be able to select from Table A based on group checkin info that doesn't exist in TableB based on same group checkin info.
For this example, I need to select a user where: ceID=1135, cID=1001, crID=1001, clID=1163 AND chDate=2022-04-21 That does not exist in Table B based on the same criteria:
// This returns user from wrong group:
select ch.user_ID FROM TableA ch
WHERE NOT EXISTS (
select 1 FROM tableB cr
WHERE ch.cID=1001 AND ch.cID=cr.cID
AND ch.crID=1001 AND ch.crID=cr.crID
AND ch.clID=1163 AND ch.clID=cr.clID
AND ch.ceID=1135 AND ch.ceID=cr.ceID
AND ch.user_ID=cr.user_ID
AND ch.chDate='2022-04-21' AND ch.chDate=cr.chDate
)
Group by ch.user_ID
ORDER BY RAND() LIMIT 1
// This returns nothing:
SELECT ch.* FROM tableA ch
left join tableB cr on ch.user_ID=cr.user_ID
WHERE ch.cID=1001 AND cr.cID=1001
AND ch.crID=1001 AND cr.crID=1001
AND ch.clID=1163 AND cr.clID=1163
AND ch.ceID=1135 AND cr.ceID=1135
AND ch.chDate='2022-04-21' AND cr.chDate='2022-04-21'
AND cr.user_ID IS NULL
GROUP BY ch.user_ID
ORDER BY RAND() LIMIT 1
;
I have gone through several different iterations of both but to no avail.
I would write it this way:
SELECT ch.* FROM tableA AS ch
LEFT OUTER JOIN tableB AS cr
ON ch.user_ID=cr.user_ID
AND cr.cID=1001
AND cr.crID=1001
AND cr.clID=1163
AND cr.ceID=1135
AND cr.chDate='2022-04-21'
WHERE ch.cID=1001
AND ch.crID=1001
AND ch.clID=1163
AND ch.ceID=1135
AND ch.chDate='2022-04-21'
AND cr.user_ID IS NULL
GROUP BY ch.user_ID
ORDER BY RAND() LIMIT 1;
If you want to put conditions on the cr
table in that outer join, put the conditions in the ON
clause. If you put the conditions in the WHERE
clause, it means the columns must be non-NULL which means there must be a match in the join. But you're looking for cases where no row with those conditions is found to satisfy the join.
By the way, I'm not sure about the GROUP BY
. Unless user_id
is the primary or unique key of tableA
, then the other columns aren't functionally dependent and the grouping should be an error. But if the column is a primary or unique key, then the grouping is a no-op, so I'm not sure why it's there.