2013-08-28 93 views
0

考慮下表SQL連接表自行尋找差異

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存在嗎? 我的頭卡住了,我相信這是一個微不足道的查詢,但我有這些日子之一。

+0

你如何配合他們?按ID還是按名稱? –

回答

1

有幾種方法可以實現這一點。一種方法是使用一個子選擇與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 
) 

另外,也可以使用外部聯接:基於@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 
+0

@wildplasser對不起,編輯錯誤 - 修復。 –

+0

謝謝大家的回答。他們都工作。由於提供了2種解決方案,因此接受了Aleks's。再次感謝。易於查詢 – Thomas

1

這與聚合:

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子句中的第一個條件會計算法語出現的次數。第二個是統計英語出現的次數。如果沒有法文版本,並且至少有一個英文版本,則通道和名稱位於結果集中。

+0

這將產生0行,因爲在您的連接中,您只需要使用't2.lang ='fr''來獲取行,但也需要't2.lang爲null' - 就是這樣必須同時'fr'和'null' –

+0

@AleksG否,問題在於那些沒有'fr'行,因爲我使用'left join',它將保留't1'的所有行然後過濾掉那些實際上匹配't2.lang ='fr''的內容 –

1

你可以做

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