删除LEFT JOIN中的重复值

时间:2014-05-13 11:08:09

标签: sql-server left-join

我的SQL字符串如下:

SELECT d.*, a.*
FROM Documents AS d 
LEFT JOIN [Document_Attachments] AS a
ON  d.[Doc No Int] = a.[Document Number]
AND d.[Revision] = a.[Document Revision]
WHERE (d.[Lock] = 'off' 
AND d.[Status] <> 'DELETED') 
OR (d.[Lock] = 'off' 
AND d.[Status] IS NULL)
ORDER BY d.[Filename] ASC

这将检索我需要的所有信息,但如果找到多个匹配项,还会显示表“d”的副本。

我只需要检索任何一个匹配项,因此我知道存在一个值。

E.g。

表d:

Doc No Int  Rev
E-0100      0
E-0200      0
E-0300      0

表a:

Document Number     Document Revision   Attachment ID
E-0100              0                   27
E-0100              0                   28
E-0200              0                   46
E-0300              0                   100
E-0300              0                   101

检索到的信息(我已删除此示例中的大多数行):

Doc No Int  Rev  Attachment ID
E-0100      0    27
E-0100      0    28
E-0200      0    46
E-0300      0    100
E-0300      0    101

我想要检索的内容:

Doc No Int  Rev  Attachment ID
E-0100      0    27
E-0200      0    46
E-0300      0    100

因此,检索哪个“附件ID”值并不重要,我只需要使用值填充列,如果找不到匹配则需要 NULL

我希望这是有道理的。

谢谢。

1 个答案:

答案 0 :(得分:0)

如果您只需要附件中的一列,我建议使用相关的子查询:

SELECT d.*,
       (SELECT TOP 1 Attachment_Id
        FROM Document_Attachments a
        WHERE d.[Doc No Int] = a.[Document Number] AND
              d.[Revision] = a.[Document Revision]
       )
FROM Documents d
WHERE (d.[Lock] = 'off' AND d.[Status] <> 'DELETED') OR
      (d.[Lock] = 'off' AND d.[Status] IS NULL)
ORDER BY d.[Filename] ASC;

如果您想要多个列,可以使用CROSS APPLY

SELECT d.*, a.*
FROM Documents d CROSS APPLY
     (SELECT TOP 1 a.*
      FROM Document_Attachments a
      WHERE d.[Doc No Int] = a.[Document Number] AND
            d.[Revision] = a.[Document Revision]
     ) a
WHERE (d.[Lock] = 'off' AND d.[Status] <> 'DELETED') OR
      (d.[Lock] = 'off' AND d.[Status] IS NULL)
ORDER BY d.[Filename] ASC;

您也可以通过在原始查询中添加group by或在子查询中使用row_number()来执行您想要的操作,但我认为这些是更简单的解决方案。