2013-07-17 34 views
0

我有以下schema找回丟失的關係在SQL

CREATE TABLE `filmati` (
    `idfilmato` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`idfilmato`) 
) ; 

CREATE TABLE `utenti` (
    `idutente` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`idutente`) 
) ; 

CREATE TABLE `utenti_has_filmati` (
    `fkutente` int(11) NOT NULL, 
    `fkfilmato` int(11) NOT NULL, 
    PRIMARY KEY (`fkutente`,`fkfilmato`), 
    KEY `fk_Utenti_has_videos_videos1_idx` (`fkfilmato`), 
    KEY `fk_Utenti_has_videos_Utenti_idx` (`fkutente`), 
    CONSTRAINT `fk_Utenti_has_videos_Utenti` FOREIGN KEY (`fkutente`) REFERENCES `utenti` (`idutente`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `fk_Utenti_has_videos_videos1` FOREIGN KEY (`fkfilmato`) REFERENCES `filmati` (`idfilmato`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ; 

和數據:

Insert into filmati VALUES (1); 
Insert into filmati VALUES (2); 
Insert into filmati VALUES (3); 

insert into utenti values(1); 
insert into utenti values(2); 
insert into utenti values(3); 

insert into utenti_has_filmati values(1,2); 
insert into utenti_has_filmati values(1,3); 
insert into utenti_has_filmati values(2,3); 
insert into utenti_has_filmati values(2,1); 
insert into utenti_has_filmati values(3,1); 
insert into utenti_has_filmati values(3,2); 

我想一個查詢,可以告訴我丟失的關係

在這種情況下:

1 1 
2 2 
3 3 

有什麼建議嗎?

回答

2

(交叉)連接兩個表,所以你得到所有filmati和所有高等學府(= cathesian產品)的組合。

然後你可以left join聯結表utenti_has_filmati加入所有現有的關係。

然後使用WHERE子句只返回那些在結合表不匹配的行

select u.idutente, f.idfilmato 
from 
    utenti u 
    cross join filmati f 
    left join utenti_has_filmati uf 
    on uf.fkutente = u.idutente and 
     uf.fkfilmato = f.idfilmato 
where 
    uf.fkfilmato is null -- Check for either field. Doesn't matter. 
+0

TY比卡羅利答案更快一些解釋 – VeNoMiS

1

可能是最快的方法如下:

select idfilmato, idutente 
from filmati 
join utenti 
left outer join utenti_has_filmati on (idfilmato = fkfilmato and idutente = fkutente) 
where fkutente is null; 
2
SELECT 
    A.idfilmato, B.idutente 
    FROM 
    filmati A,utenti B 
    WHERE NOT EXISTS 
    (
    SELECT 1 
    FROM 
     utenti_has_filmati AB 
    WHERE 
     AB.fkutente = A.idfilmato AND 
     AB.fkfilmato = B.idutente 
) 
+0

記錄爲什麼使用舊的語法?爲什麼不從'filmati CROSS JOIN utenti B'? –

+0

你是完全正確的,但語義上它們是相同的。我更喜歡使用逗號語法而不是交叉連接來提醒我,如果可能,必須避免它。 – phoenixgr