时间:2016-05-30 02:50:48

标签: sql sql-server-2012

关于如何删除左外连接中的重复记录,有很多问题。我在这两个表Table1和Table2之间有一个简单的左外连接,其中Table1与Table2有一对多的关系(我在这里直接写了这个简单的查询只是为了解释我所追求的并且它不是实际的查询),< / p>

SELECT a.ID, a.Name, b.Value
FROM Table1 a 
LEFT OUTER JOIN Table2 b ON a.ID == b.Table1_ID

现在返回结果,

ID    Name     Value
1     Test1    TestValue1
1     Test1    TestValue2
1     Test1    TestValue3
1     Test1    NULL
2     Test2    TestValue4
2     Test2    NULL
2     Test2    TestValue5

现在这个输出是正确的,我知道这是一个正确的行为。但是有什么方法可以获得以下输出。这可能很简单,但我之前没有这样做,每次我搜索我遇到问题的解决方案和线程要求删除重复项。我不想删除重复项。只想在下面显示Table1中的值,

ID    Name     Value
1     Test1    TestValue1
               TestValue2
               TestValue3
               NULL
2     Test2    TestValue4
               NULL
               TestValue5

2 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER确定相关值中的第一行:

WITH CTE AS(
    SELECT 
        a.ID, 
        a.Name, 
        b.Value,
        Rn = ROW_NUMBER() OVER(PARTITION BY a.ID ORDER BY (SELECT NULL))
    FROM Table1 a 
    LEFT JOIN Table2 b 
        ON a.ID = b.Table1_ID
)
SELECT
    ID  = CASE WHEN Rn = 1 THEN CONVERT(VARCHAR(10), a.ID) ELSE '' END),
    Name = CASE WHEN Rn = 1 THEN Name ELSE '' END),
    Value
FROM CTE

ORDER BY (SELECT NULL))替换为您希望ROW_NUMBER所依据的列。

答案 1 :(得分:1)

通常,这种类型的数据处理将在应用程序层中完成。您可以在数据库中执行此操作,但这不是一个好主意。 SQL结果集是无序的,除非您明确拥有order by

SELECT (CASE WHEN seqnum = 1 THEN id END) as id,
       (CASE WHEN seqnum = 1 THEN name END) as name,
       value
FROM (SELECT a.ID, a.Name, b.Value,
             ROW_NUMBER() OVER (PARTITION BY a.id, a.name ORDER BY (SELECT NULL)) as as seqnum
      FROM Table1 a LEFT OUTER JOIN
           Table2 b
           ON a.ID = b.Table1_ID
     )
ORDER BY id, name, seqnum;