请在继续之前阅读此内容:Filter an unfiltered table against a whitelist table
所以,我目前有一个白名单表设置,如引用的链接所示,我遇到了由该表提出的另一个问题,即检查每列的UNIQUENESS。作为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
仍然按预期正常工作,但问题从这里开始。
我是否可以使用此数据,并重新选择白名单表,以便我可以将每个条目作为一行添加类似......
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并重新选择它,但我想知道是否可以在一个SQL查询调用而不是两个中执行它。
编辑:哎呀,上面的示例中有一个错误(意外地使用了真实架构xD)
Edit2: Doh,我突然想到为什么会让事情变得复杂,为什么不只是简单地使用它......
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
这正是这里的问题。如果我在country,region,item上设置了一个唯一键,并且我执行以下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.
因此,这篇文章的想法是列出列表中的所有重复白名单,以便运营商可以决定要保留什么和删除什么。
答案 0 :(得分:1)
不热衷于这个解决方案,但可行: -
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)