2012-09-20 108 views
0

我有四个表a,b,c,d。在表a我有一对id, name。在表b我有一对idx, idyb.idy来自表a.id。在表c, d我有一对id, value这是有关表b.idx简单但嵌套的SELECT查询

我必须执行这样的查询:

SELECT c.value, d.value 
FROM a,b,c,d 
WHERE a.name = "test" AND b.idy = a.id AND (c.id = b.idx AND d.id = b.idx) 

的问题是有时有在表中丢失记录c, d所以AND将返回零条记录,但我需要的结果,如果有可以参阅cd。此外,我不能使用OR,因为它也为两个表返回其他行。

我想会有一个解决方案,使用UNION甚至只是嵌套SELECT s。我更喜欢不使用JOIN或使用单独的quires。

在此先感谢!

更新:

之所以使用JOIN是性能避免。我正在处理的结构现在比这个更复杂,所以我确信JOIN在未来的将来我会遇到严重的性能问题。

+2

为什么你不喜欢的JOIN?这似乎是一个经典的'LEFT JOIN'用例。 – Vikdor

+0

我在原文中解释了原因 – Mahdi

+1

而实际上您已经在使用JOIN。你认为'FROM a,b,c,d'是什么意思?至于性能,“没有得到正确的结果”看起来像是一个严重的性能问题... – LSerni

回答

1

我想你想使用LEFT JOIN

SELECT c.value, d.value 
FROM a 
LEFT JOIN b 
    ON a.id = b.idy 
LEFT JOIN c 
    ON b.idx = c.id 
LEFT JOIN d 
    ON b.idx = d.id 
WHERE a.name = "test" 

使用逗号连接语法是INNER JOIN这就要求记录所有表中可用。

如果您需要在审查JOIN语法帮助有一个有益的指导:

A Visual Explanation of SQL Joins

+0

谢谢bluefeet!它工作起来并且比'RedFilter'解决方案稍快。你有什么想法,为什么? – Mahdi

1
select c.value, d.value 
from a 
inner join b on b.idy = a.id 
left outer join c on c.id = b.idx 
left outer join d on d.id = b.idx 
where a.name = "test" 
    and coalesce(c.id, d.id) is not null 
+0

谢谢RedFilter,我测试你的查询,它的工作! :) ...要测试其他答案... – Mahdi

+1

@Mahdi为了阐明我的查询的功能,它只返回记录,其中有一个匹配的表'a' *和*'b',以及匹配要么'c' *要么*'d'。 – RedFilter

+0

是的,但它比'bluefeet'查询稍慢。你知道为什么吗?使用查询有什么好处吗?再次感谢! – Mahdi

1
SELECT c.value, d.value 
FROM a,b,c,d 
WHERE a.name = "test" AND b.idy = a.id AND (c.id = b.idx AND d.id = b.idx) 
UNION 
SELECT c.value, NULL 
FROM a,b,c 
WHERE a.name = "test" AND b.idy = a.id AND c.id = b.idx AND NOT EXISTS(SELECT NULL FROM d where d.id = b.idx) 
UNION 
SELECT NULL, d.value 
FROM a,b,d 
WHERE a.name = "test" AND b.idy = a.id AND d.id = b.idx AND NOT EXISTS(SELECT NULL FROM c where c.id = b.idx) 
+0

谢谢JosephH!你的查询可以工作,但比别人慢几倍。但是我知道我要求通过'UNION'或嵌套'SELECT'来完成。无论如何谢谢你! :) – Mahdi

+1

@Mahdi我认为使用它的主要好处是,当行不存在于c或d中时,可以设置'(NULL)'的值。据我所知,我不认为这是可能的,如果你正在使用'JOIN' – JosephH

+0

对不起,我不明白它的确切含义。可以请你多解释一下,谢谢... – Mahdi