【问题标题】:Eliminate duplicates of records in the column on JOIN消除 JOIN 列中的重复记录
【发布时间】:2018-10-22 15:14:53
【问题描述】:

初始数据示例:

  Table 1                                             Table 2
|  ID   |   Name   |  Cost   |  Cost2  |           |  ID   |   Info1   |   Info2   |
|-------|----------|---------|---------|           |-------|-----------|-----------|
|  1    |   Name1  |   20    |   50    |           |  1    |   text1   |   text1   |
|  2    |   Name2  |   30    |   10    |           |  1    |   text1   |   text1   |
|  2    |   Name22 |   30    |   40    |           |  1    |   text1   |   text1   |
|  3    |   Name3  |   20    |   50    |           |  2    |   text21  |   text21  |
|  4    |   Name4  |   30    |   70    |           |  2    |   text22  |   text22  |
                                                   |  2    |   text23  |   text23  |
                                                   |  2    |   text24  |   text24  |

在我的初始数据中,我通过字段 ID 在 2 个表之间建立了关系。我需要将第二张桌子加入第一张桌子。 所以这是Leftjoin by table1.ID = table2.ID 的简单结果

|  ID   |   Name   |  Cost   |  Cost2  |   Info1   |   Info2   |  
|-------|----------|---------|---------|-----------|-----------|                                                   
|  1    |   Name1  |   20    |   50    |   text1   |   text1   |                                                   
|  1    |   Name1  |   20    |   50    |   text1   |   text1   |  
|  1    |   Name1  |   20    |   50    |   text1   |   text1   |  
|  2    |   Name2  |   30    |   10    |   text21  |   text21  |  
|  2    |   Name2  |   30    |   10    |   text22  |   text22  |  
|  2    |   Name2  |   30    |   10    |   text23  |   text23  | 
|  2    |   Name2  |   30    |   10    |   text24  |   text24  |
|  2    |   Name22 |   60    |   40    |   text21  |   text21  | 
|  2    |   Name22 |   60    |   40    |   text22  |   text22  | 
|  2    |   Name22 |   60    |   40    |   text23  |   text23  | 
|  2    |   Name22 |   60    |   40    |   text24  |   text24  | 

如何在不通过join 对字段(成本、成本2)进行复制的情况下获得结果

预期结果:

|  ID   |   Name   |  Cost   |  Cost2  |   Info1   |   Info2   |  
|-------|----------|---------|---------|-----------|-----------|                                                   
|  1    |   Name1  |   20    |   50    |   text1   |   text1   |                                                   
|  1    |   Name1  |  NULL   |  NULL   |   text1   |   text1   |  
|  1    |   Name1  |  NULL   |  NULL   |   text1   |   text1   |  
|  2    |   Name2  |   30    |   10    |   text21  |   text21  |  
|  2    |   Name2  |  NULL   |  NULL   |   text22  |   text22  |  
|  2    |   Name2  |  NULL   |  NULL   |   text23  |   text23  | 
|  2    |   Name2  |  NULL   |  NULL   |   text24  |   text24  |
|  2    |   Name22 |   30    |   40    |   text21  |   text21  | 
|  2    |   Name22 |  NULL   |  NULL   |   text22  |   text22  | 
|  2    |   Name22 |  NULL   |  NULL   |   text23  |   text23  | 
|  2    |   Name22 |  NULL   |  NULL   |   text24  |   text24  | 

【问题讨论】:

  • 您可以在使用连接查询时尝试使用 distinct。这能正确解决问题吗?

标签: sql sql-server sql-server-2017


【解决方案1】:

您可以尝试使用row_number窗口函数在子查询中制作行号,然后通过CASE WHEN获取CostCost2,其中行号为1

SELECT ID,
    Name,
    CASE WHEN rn = 1 THEN Cost end, 
    CASE WHEN rn = 1 THEN Cost2 end,  
    Info1,
    Info2      
FROM (
    SELECT  
       t1.ID,
       Name,
       Cost,
       Cost2,
       Info1,
       Info2,   
       row_number() over(partition by Name order by Info1) rn
    FROM Table1 t1 JOIN table2 t2 on t1.id = t2.id
) t1

sqlfiddle

【讨论】:

    【解决方案2】:

    join 需要一个“行号”。您的表没有,但您可以使用row_number() 添加一个:

    select coalesce(t1.id, t2.id) as id,
           t1.name, t1.cost, t2.info1, t2.info2
           . . .
    from (select t1.*, row_number() over (partition by id order by (select null)) as seqnum
          from table1 t1
         ) full join
         (select t2.*, row_number() over (partition by id order by (select null)) as seqnum
          from table2 t2
         ) t2
         on t1.id = t2.id and t1.seqnum = t2.seqnum;
    

    唉,您不会使用这种方法获得name。但这是有道理的。它仅在table1 中,因此不应出现在每个匹配的行上。

    编辑:

    这并不完全正确。您希望行重复。然后值不出现。我认为这是条件逻辑:

    如果你真的需要它:

    select t1.id, t1.name,
           (case when row_number() over (partition by t1.id order by (select null)) = 1 then cost END) as Cost,
           t2.info1, t2.info2
    from table1 t1 join
         table2 t2
         on t1.id = t2.id ;
    

    【讨论】:

    • 谢谢你的回答,太好了。如果我有机会接受这两个答案,我肯定会这样做。如果可以请编辑case表达式,这里没有结束。
    猜你喜欢
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    相关资源
    最近更新 更多