Ada*_*ley 3 mysql join condition where
我正在尝试过滤具有非唯一事务 ID 的表,该表已连接到 1 个公共列上的产品表。过滤器需要如下:
equal to :group1 AND
NOT equal to :group2 AND
NOT equal to :group3
Run Code Online (Sandbox Code Playgroud)
我最初从以下查询开始,但没有AND rk_group <> ____条件。
SELECT COUNT(DISTINCT txn_id)
FROM 1_txns
INNER JOIN 2_products USING (sku)
WHERE rk_group = :group1
AND rk_group <> :group2
AND rk_group <> :group3
;
Run Code Online (Sandbox Code Playgroud)
我也试过
SELECT COUNT(DISTINCT txn_id)
FROM 1_txns
INNER JOIN 2_products USING (sku)
WHERE rk_group NOT IN ( :group2, :group3)
;
Run Code Online (Sandbox Code Playgroud)
我还尝试了多种连接和 IN() 和 NOT IN() 的组合,它仍然返回所有团队 ID,包括那些存在 NOT 组的团队 ID。
有人可以指出我正确的方向吗?
与查询相关的架构信息:
table 1_txns
(txn_id, sku)
table 2_products
(sku, rk_group)
Run Code Online (Sandbox Code Playgroud)
样本数据
Txn_id, rk_group
------
1,group1
1,group2
2,group1
3,group1
3,group3
Run Code Online (Sandbox Code Playgroud)
如果以上是我的数据,group1 是我的 = 组,group2 和 3 是我的 != 组,那么我应该返回 1 的行数。这是 txn id '2'。到目前为止,我尝试过的所有方法都会返回 3 的计数。
注意:2_products 表中只有 3 个不同的 rk_groups。
你的 WHERE 子句没有多大意义,因为它单独应用于每一行,检查相同的值是否等于a并且同时不等于b或c- 当然,它不会等于b或c如果是a。因此,您想要的是将条件作为一个整体应用于一组行——更具体地说,应用于共享相同txn_id.
因此,您需要使用 GROUP BY 并将条件应用于行组 HAVING。此查询将为您提供txn_id符合您要求的值列表:
SELECT
t.txn_id
FROM
1_txns AS t
INNER JOIN 2_products AS p USING (sku)
GROUP BY
t.txn_id
HAVING
COUNT(p.rk_group = :group1 OR NULL) > 0
AND COUNT(p.rk_group IN (:group2, group3) OR NULL) = 0
;
Run Code Online (Sandbox Code Playgroud)
由于您似乎不需要列表,只需要其项目数,因此请使用上面的派生表来计算行数:
SELECT
COUNT(*)
FROM
(
SELECT
txn_id
FROM
1_txns AS t
INNER JOIN 2_products AS p USING (sku)
GROUP BY
t.txn_id
HAVING
COUNT(rk_group = :group1 OR NULL) > 0
AND COUNT(rk_group IN (:group2, group3) OR NULL) = 0
) AS s
;
Run Code Online (Sandbox Code Playgroud)
如您所见,COUNT(DISTINCT ...)没有必要:派生表是分组依据txn_id,因此不能返回重复项——因此,COUNT(*)足以获得正确的结果。
如果您不知道,该OR NULL位让 COUNT 函数只计算匹配项并忽略不匹配项,如本答案中的详细说明:
| 归档时间: |
|
| 查看次数: |
16356 次 |
| 最近记录: |