同一列上的多个 WHERE 条件 =val1 但不 =val2 或 val3

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。

And*_*y M 6

你的 WHERE 子句没有多大意义,因为它单独应用于每一行,检查相同的值是否等于a并且同时不等于bc- 当然,它不会等于bc如果是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 函数只计算匹配项并忽略不匹配项,如本答案中的详细说明:

  • @AndriyM 您可以在 mysql 中“简化”`COUNT(BooleanExpression OR NULL)` 为 `SUM(BooleanExpression)`。 (2认同)
  • @Sillycubeᵀᴹ:非常正确,我在我的答案中交替建议前者和后者(有时两者兼而有之)。`COUNT(boolean OR NULL)` 将是我个人的偏好,因为它表达了我更好地计数的意图(或者我认为),但我承认可能有很多人更喜欢使用 `SUM(boolean)` – 而且我可以理解他们为什么会这样做。 (2认同)