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)
请在继续之前阅读此内容:
所以,我目前有一个白名单 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)