[英]Conditionally selecting elements of a CSV column value in MySQL
我有两个表, targets
和rulesets
。 rulesets
表包含一个target_ids
列,它是主键 ID 到targets
的 CSV,我希望SELECT
返回 ZCC8D68C551C4A9A6D551C4A9A6D5313E07DE4DEAFDZ 中的任何元素对targets
的表引用完整性字段具有特定行的引用完整性。
有什么方法可以在不需要创建临时表的情况下完成此操作?
我知道此问题的一些解决方案会将 CSV 值提取到临时表中,例如此答案: https://stackoverflow.com/a/17043084/342692 ,但我试图避免使用临时表由于权限限制。 我也知道FIND_IN_SET
对于将给定值与 CSV 列表进行比较很有用,但在这种情况下似乎没有帮助。
这是架构和目标的示例,以及具有相同内容的 DB fiddle 的链接:
CREATE TABLE IF NOT EXISTS `targets` (
`id` int(6) unsigned,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `rulesets` (
`id` int(6) unsigned,
`target_ids` text,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `targets` VALUES
(1),
(2),
(3);
INSERT INTO `rulesets` VALUES
(1, '2,3,4');
-- what targets exist in `targets` table but not in the CSV ruleset?
-- returns [1]
select t.id from targets t where find_in_set(t.id, (select target_ids from rulesets where id=1)) = 0;
-- what targets exist in both the `targets` table and the CSV ruleset?
-- returns [2,3]
select t.id from targets t where find_in_set(t.id, (select target_ids from rulesets where id=1)) > 0;
-- what targets do not exist in `targets` table but are in the CSV ruleset?
-- returns [4]
-- ???
这是一个想法,使用从 0-9 的整数 (i) 组成的简单实用程序表 (ints) ...
-- what targets exist in `targets` table but not in the CSV ruleset?
SELECT a.id target_id
FROM targets a
LEFT
JOIN
( SELECT DISTINCT r.id
, SUBSTRING_INDEX(SUBSTRING_INDEX(r.target_ids,',',i.i+1),',',-1) target_id
FROM rulesets r
JOIN ints i
) b
ON b.target_id = a.id
WHERE b.id IS NULL;
-- what targets exist in both the `targets` table and the CSV ruleset?
SELECT a.id target_id
FROM targets a
JOIN
( SELECT DISTINCT r.id
, SUBSTRING_INDEX(SUBSTRING_INDEX(r.target_ids,',',i.i+1),',',-1) target_id
FROM rulesets r
JOIN ints i
) b
ON b.target_id = a.id;
-- what targets do not exist in `targets` table but are in the CSV ruleset?
SELECT b.target_id
FROM targets a
RIGHT
JOIN
( SELECT DISTINCT r.id
, SUBSTRING_INDEX(SUBSTRING_INDEX(r.target_ids,',',i.i+1),',',-1) target_id
FROM rulesets r
JOIN ints i
) b
ON b.target_id = a.id
WHERE a.id IS NULL;
对于最后一个查询,通常情况下,您会颠倒上面表格的顺序以避免使用 RIGHT JOIN,但我这样写是为了突出它与第一个查询的相似性
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.