如何从连接的sql语句中消除重复的结果

时间:2011-11-23 14:26:23

标签: sql inner-join

我有四张相关的表:

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

有些但不是所有记录都是重复的。只有TABLE D中具有相同FK到TABLE B的记录。

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

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

但那不可能吗?

谢谢!

3 个答案:

答案 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

上运行良好

答案 1 :(得分:-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

答案 2 :(得分:-1)

您似乎有笛卡尔加入。

您可以尝试将DISTINCT放在您的列定义之前,或者您可以将子查询链接在一起。