2011-11-23 60 views
0

重复的结果具有被这样相关的四个表:我如何消除加入SQL语句

TABLE A: 1 to many with TABLE B 
TABLE B: 1 to many with TABLE C 
TABLE D: many to 1 with TABLE B 

我想创建一个结果集,它不包含任何重复。

SELECT A.f1 
     A.f2 
     B.f1 
     C.f1 
     D.f1 
from A LEFT JOIN (B INNER JOIN D on D.fk_b = B.id) on A.id = B.fk_a 
     LEFT JOIN C on C.fk_b = B.id 

有些但不是全部记录是重复的。只有具有相同FK的TABLE DTABLE B的记录。

如果有2个相同的D.fk_B字段,那么我想只选择第一个。我的INNER JOIN会变成类似于:

B INNER JOIN TOP 1 D on..... 

但这不可能?

谢谢!

+2

如果他们确切的重复,你应该使用'选择DISTINCT' 。 – Viruzzo

+0

no there not exact duplicates :( – jorrebor

+0

定义你的意思是“不完整的重复” – onedaywhen

回答

-1

尝试

SELECT DISTINCT A.f1 
     A.f2 
     B.f1 
     C.f1 
     D.f1 
from A LEFT JOIN (B INNER JOIN D on D.fk_b = B.id) on A.id = B.fk_a 
     LEFT JOIN C on C.fk_b = B.id 

你可以这样做:

B INNER JOIN TOP 1 D on..... 

像这样

B INNER JOIN (SELECT TOP 1 fields from table) D ON ... 

试试这个:

SELECT DISTINCT A.f1 
      A.f2 
      B.f1 
      C.f1 
      D.f1 
    from A 
    LEFT JOIN (B INNER JOIN (SELECT DISTINCT fk_b FROM D) D on D.fk_b = B.id) 
     on A.id = B.fk_a 
    LEFT JOIN C on C.fk_b = B.id 
+0

B INNER JOIN(从表中选择TOP 1字段)D ON ...给我一个语法错误(我真的使用“table”还是我的表名?这是D对吗? – jorrebor

+0

使用您的表名和字段列表 – Sparky

+0

您可以用SQL查询(从D中选择top 1)替换表名(在本例中为D)。然而,你的例子不太清楚,但我会修改答案查询做我认为你想要的... – Sparky

-1

看起来你有笛卡尔连接。

你可以尝试在你的列定义的前面添加DISTINCT,或者你可以这样子查询来将表链接在一起。

+0

我想我必须使用子查询。主要是想知道它是否可以做得更加优雅。 – jorrebor

+0

不怕我的朋友 –

2

假设所讨论的结构是近所示波纹管的一个,

Tables

下面的SELECT语句会显示你刚才的主键,简单地给一个想法关于什么数据被返回。

SELECT 
    A.id AS `A_id`, 
    B.id AS `B_id`, 
    COALESCE(C.id, 0) AS `C_id`, 
    COALESCE(
    (SELECT D.id FROM D WHERE D.fk_b = B.id LIMIT 1), 0 
) AS `D_id` 
FROM B 
INNER JOIN A ON (B.fk_a = A.id) 
LEFT JOIN C ON (B.id = C.fk_b); 

这可是你自找的选择:以上测试

SELECT 
    A.f1 AS `A_f1`, 
    A.f2 AS `A_f2`, 
    B.f1 AS `B_f1`, 
    COALESCE(C.f1, '-') AS `C_f1`, 
    COALESCE(
    (SELECT D.f1 FROM D WHERE D.fk_b = B.id LIMIT 1), '-' 
) AS `D_f1` 
FROM B 
INNER JOIN A ON (B.fk_a = A.id) 
LEFT JOIN C ON (B.id = C.fk_b); 

代码和工作的罚款在MySQL 5.6