mysql select 来自 Table A(在条件下)而不在 Table B(在相同条件下)
mysql select from Table A (on conditions) where not in Table B (on same conditions)
我在这件事上玩得很开心。我一直在阅读和尝试不同的解决方案,但 none 对我有用。我已经创建了一个抽奖系统,需要 select 满足所有条件的用户,这些用户以前没有根据相同条件 selected。
TableA 字段,用户已签到位置:
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
注意:1-5 和 11-15 是同一个用户,但是组类别 ID 不同
TableB 个字段,用户之前 select 被选为获胜者:
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 存储已签入特定组的用户。 Table 当来自该组的用户 select 参加抽奖时,B 会存储该用户。
我需要能够 select 来自 Table A 基于群组签到信息,而 TableB 基于相同的群组签到信息。
对于这个例子,我需要 select 一个用户,其中:
ceID=1135、cID=1001、crID=1001、clID=1163 和 chDate=2022-04-21
根据相同的标准,Table B 中不存在:
// 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
;
我已经对两者进行了几次不同的迭代,但都无济于事。
我会这样写:
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;
如果要在该外部联接中的 cr
table 上放置条件,请将条件放置在 ON
子句中。如果将条件放在 WHERE
子句中,则意味着列必须是 non-NULL,这意味着连接中必须有匹配项。但是您正在寻找 no 符合这些条件的行满足连接的情况。
顺便说一下,我不确定 GROUP BY
。除非 user_id
是 tableA
的主键或唯一键,否则其他列在功能上不相关,分组应该是错误的。但是,如果该列是主键或唯一键,那么分组就是 no-op,所以我不确定它为什么在那里。
我在这件事上玩得很开心。我一直在阅读和尝试不同的解决方案,但 none 对我有用。我已经创建了一个抽奖系统,需要 select 满足所有条件的用户,这些用户以前没有根据相同条件 selected。
TableA 字段,用户已签到位置:
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
注意:1-5 和 11-15 是同一个用户,但是组类别 ID 不同
TableB 个字段,用户之前 select 被选为获胜者:
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 存储已签入特定组的用户。 Table 当来自该组的用户 select 参加抽奖时,B 会存储该用户。
我需要能够 select 来自 Table A 基于群组签到信息,而 TableB 基于相同的群组签到信息。
对于这个例子,我需要 select 一个用户,其中: ceID=1135、cID=1001、crID=1001、clID=1163 和 chDate=2022-04-21 根据相同的标准,Table B 中不存在:
// 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
;
我已经对两者进行了几次不同的迭代,但都无济于事。
我会这样写:
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;
如果要在该外部联接中的 cr
table 上放置条件,请将条件放置在 ON
子句中。如果将条件放在 WHERE
子句中,则意味着列必须是 non-NULL,这意味着连接中必须有匹配项。但是您正在寻找 no 符合这些条件的行满足连接的情况。
顺便说一下,我不确定 GROUP BY
。除非 user_id
是 tableA
的主键或唯一键,否则其他列在功能上不相关,分组应该是错误的。但是,如果该列是主键或唯一键,那么分组就是 no-op,所以我不确定它为什么在那里。