繁体   English   中英

SQL联接表到自我发现差异

[英]SQL join table to self to find difference

考虑下表

CREATE TABLE `temp` (
  `id` int(11) NOT NULL,
  `lang` char(2) COLLATE utf8_unicode_ci NOT NULL,
  `channel` char(2) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`,`lang`,`channel`)
)

insert into `temp` (`id`, `lang`, `channel`, `name`) values('1','fr','ds','Jacket');
insert into `temp` (`id`, `lang`, `channel`, `name`) values('1','en','ds','Jacket');
insert into `temp` (`id`, `lang`, `channel`, `name`) values('2','en','ds','Jeans');
insert into `temp` (`id`, `lang`, `channel`, `name`) values('3','en','ds','Sweater');
insert into `temp` (`id`, `lang`, `channel`, `name`) values('1','de','ds','Jacket');

问题是我怎么能找到fr不存在lang en的条目? 我的头被卡住了,我相信这是一个琐碎的查询,但是我现在正处于其中。

有几种方法可以实现此目的。 一种方法是使用带有not exists子句的子选择:

select id, channel
from temp t1
where t1.lang = 'en'
and not exists (
  select 1
  from temp t2
  where t2.lang = 'fr'
  and t1.id = t2.id
)

或者,您可以使用外部联接:

select t1.id, t1.channel
from temp t1
left outer join temp t2 on t1.id = t2.id
where t1.lang = 'en'
and t2.id is null

基于@AleksG

SELECT t1.id, t1.channel, t1.name
FROM temp t1
LEFT JOIN temp t2 ON t1.id = t2.id AND t2.lang = 'fr'
WHERE t1.lang = 'en' AND t2.lang IS NULL 

您可以通过聚合来做到这一点:

select t.channel, t.name
from temp t
group by t.channel, t.name
having sum(case when t.lang = 'fr' then 1 else 0 end) = 0 and
       sum(case when t.lang = 'en' then 1 else 0 end) > 0;

having子句中的第一个条件计算了法语出现的次数。 秒数计算英语出现的次数。 如果法语没有,而英语至少有一个,则频道和名称都在结果集中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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