Mysql

同一列上的多個 WHERE 條件 =val1 但不 = val2 或 val3

  • December 18, 2015

我正在嘗試過濾具有非唯一事務 id 的表,該表連接到 1 個公共列上的產品表。過濾器需要如下:

equal to :group1 AND
NOT equal to :group2 AND
NOT equal to :group3

我最初從以下查詢開始,但沒有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
                   ;

我也試過

SELECT COUNT(DISTINCT txn_id)
                   FROM 1_txns
                   INNER JOIN 2_products USING (sku)
                   WHERE rk_group NOT IN ( :group2, :group3)
                   ;

我還嘗試了 join 和 IN() 和 NOT IN() 的多種組合,它仍然返回所有團隊 ID,包括那些存在 NOT 組的團隊 ID。

有人可以指出我正確的方向嗎?

與查詢相關的架構資訊:

table 1_txns
(txn_id, sku)

table 2_products
(sku, rk_group)

樣本數據

Txn_id, rk_group


------

   1,group1
   1,group2
   2,group1
   3,group1
   3,group3

如果上面是我的數據,group1 是我的 = 組,group2 和 3 是我的 != 組,那麼我應該返回 1 的行數。這是 txn id ‘2’。到目前為止我嘗試過的所有方法都將返回 3。

注意:2_products 表中只有 3 個不同的 rk_groups。

您的 WHERE 子句沒有多大意義,因為它單獨應用於每一行,檢查相同的值是否等於a和同時不等於b或毫無意義c——當然,它不會等於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
;

由於您似乎不需要列表,只需要其項目數,因此使用上面的作為派生表來計算行數:

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
;

如您所見,COUNT(DISTINCT ...)這不是必需的:派生表是分組依據txn_id,因此不能返回重複項——因此,COUNT(*)足以獲得正確的結果。

如果您不知道,該OR NULL位允許 COUNT 函式計數僅匹配並忽略不匹配,如本答案中詳細說明的那樣:

引用自:https://dba.stackexchange.com/questions/123967