繁体   English   中英

有条件地选择 MySQL 中 CSV 列值的元素

[英]Conditionally selecting elements of a CSV column value in MySQL

我有两个表, targetsrulesets 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM