SELECT WHERE IN 以 GROUP_CONCAT 作为输入

SELECT WHERE IN with GROUP_CONCAT as input

请在继续之前阅读此内容:

所以,我目前有一个白名单 table 设置,如参考 link 所示,我遇到了 table 提出的另一个问题,即, 检查每列的唯一性。作为 MySQL 的规范,不可能将 NULL 列设置为 UNIQUE,因此,我决定想出一个不同的解决方案来检查行是否重复,方法是使用 SELECT GROUP BY查询如下。

SELECT GROUP_CONCAT(ID) AS IDs, country, region, item, count(*) AS amount
FROM whitelist

现在,为了检查该项目是否重复,我将其扭曲到另一层之上。

SELECT IDs, country, region, item, amount
FROM (SELECT GROUP_CONCAT(ID) AS IDs, country, region, item, count(*) AS amount
      FROM whitelist) tmp
WHERE amount > 1

仍然按预期正常工作,但问题从这里开始。

我是否可以使用这些数据和 RE-SELECT 白名单 table 这样我就可以将每个条目作为一行,例如...

SELECT ID, country, region, item
FROM whitelist
WHERE ID IN (SELECT group_concat(ID)
               FROM (SELECT group_concat(ID) AS ID, country, region, item, COUNT(*) AS AMOUNT
                       FROM whitelist
                      GROUP BY country, region, item) tmp
              WHERE AMOUNT > 1)

当然,我可以只使用 PHP 并分解 group_concat ID 并重新 select 它,但我想知道是否可以在一个 SQL查询调用而不是两个。

编辑: 糟糕,上面的例子有一个错误(不小心在那里使用了真实的模式 xD)

Edit2: 哦,我突然想到为什么要把事情复杂化,为什么不简单地用这个...

SELECT wl1.ID, wl1.country, wl1.region, wl1.item, wl1.reason
  FROM whitelist wl1, 
       (SELECT country, region, item
          FROM whitelist
         GROUP BY country, region, item
        HAVING count(*) > 1) wl2
 WHERE wl1.country = wl2.country AND
       wl1.region = wl2.region AND
       wl1.item = wl2.reason

... 但仍然失败,因为您不能在两个 NULL 列上使用 =。呃,那么近又那么远 >.<

收件人: Bill Karwin

这正是问题所在。如果我在国家、地区、项目上设置唯一键,并执行以下 SQL,就会发生这种情况。

INSERT INTO whitelist(country, region, item) VALUES ('Taiwan', 'Asia', 'PC');
INSERT INTO whitelist(country, region, item) VALUES ('Taiwan', 'Asia', 'PC');
-- Would fail due to UNIQUE check

但是,如果我包含任何通配符,也就是 NULL,就会发生这种情况。

INSERT INTO whitelist(country, region, item) VALUES (NULL, 'Asia', 'Rice');
INSERT INTO whitelist(country, region, item) VALUES (NULL, 'Asia', 'Rice');
-- Would succeed due to UNIQUE does not check NULL columns.

因此这个post的想法是将所有重复的白名单列在一个列表中,以便操作员可以决定保留什么和删除什么。

不喜欢这个解决方案,但可行:-

SELECT a.ID, 
        a.country, 
        a.region, 
        a.item
FROM whitelist a
INNER JOIN 
(
    SELECT group_concat(ID) AS ID, USERNAME, COMPNAME, PUBLISHER, NAME, VERSION, COUNT(*) AS AMOUNT
    FROM software_checklist
    GROUP BY USERNAME, COMPNAME, PUBLISHER, NAME, VERSION 
    HAVING AMOUNT > 1
) tmp
ON FIND_IN_SET(a.ID, tmp.ID)