【问题标题】:how to merge the value of two rows in one 'Duplicate IDs'如何将两行的值合并到一个“重复 ID”中
【发布时间】:2017-10-26 10:53:08
【问题描述】:

我试图找到答案,但我发现的任何东西都不适用于我的情况,因此我将不胜感激:

场景:我的客户在一个表中具有 ID 和个人信息,然后我在另一个表中指示属于这些 ID 的注释。 当我加入表格时,我会在多行中得到多个注释。如下图。

T1. ID -T1. Name    -T1. Birthday   -T2. Note                  -Row number
2      -Peter       -11/20/1990     -deciding                  -1
2      -Peter       -11/20/1990     -purchased                 -2
3      -David       -12/22/1962     -Presentation scheduled    -1  
3      -David       -12/22/1962     -Presentation completed    -2
3      -David       -12/22/1962     -Purchased                 -3
4      -Anna        -5/07/1992      -Ignored                   -1

我一直在徘徊的是如何在第一行的末尾添加注释 2 和 3 并消除重复项?

T1. ID -T1. Name    -T1. Birthday   -T2. Note               -Note_2      -Note_3
2      -Peter       -11/20/1990     -deciding               -purchased  
3      -David       -12/22/1962     -Presentation scheduled -Presentation -completed    Purchased
4      -Anna            -5/07/1992  -Ignored                -Null        -Null 

您可以使用此查询来查看表格:

declare  @t1  table ( ID int not null,
                      Name varchar (50),
                      birthday date)

declare @t2 table (ID int not null,
                    Note nvarchar(max))


insert into @t1 values ( 2 , 'Peter' , '11/20/1990')
insert into @t1 values ( 3 , 'David' ,'12/22/1962')
insert into @t1 values ( 4 , 'Anna' , '5/07/1992')

insert into @t2 values (2 , 'deciding')
insert into @t2 values (2 ,'purchased')
insert into @t2 values (3 ,'Presentation scheduled')
insert into @t2 values (3 ,'Presentation completed')
insert into @t2 values (3 ,'Purchased')
insert into @t2 values (4 ,'Ignored')



SELECT * 
        , ROW_NUMBER() OVER (PARTITION BY t1.ID ORDER BY t2.id) AS 'ROW NUMBER'
FROM @t1 as t1
left outer join @t2 AS t2 ON t1.ID = t2.ID 

【问题讨论】:

  • 查看您的 SQL 代码添加查看 declare @t1 tableROW_NUMBER() OVER (PARTITION BY@t1 我相信您使用的是 SQL-server 而不是 MySQL。所以请更正你的标签。
  • 基本上使用 ROW_NUMBER() 为每个用户创建递增的 id,然后使用 PIVOT 或条件聚合将它们放在一起。我的一个问题是,你是否总是有 x# 的笔记,换句话说,它总是 3 或更少吗?如果您想要包含动态的最大注释数,则需要使用动态 SQL 和 Pivot/条件聚合来实现
  • @Matt 非常感谢您的帮助Matt,数量可以增加,不限于1-3。我对动态 SQL 了解不多,最近才开始研究这个概念。如果您能向我推荐好的资源,我将不胜感激。
  • 取决于您使用的平台? sql服务器?我会搜索您的平台动态枢轴,您应该会找到一些参考资料。它的关键是在按用户分区的笔记表上创建一个 ROW_NUMBER。但要小心,你真的不想在列中太宽,所以你可能想要一个最大值,这样它就不会变得疯狂。此外,您可能会考虑将备注记录连接到 1 个字段的备注字段,但我想这取决于您的使用
  • @PedramSalamati 考虑使用链接问题的答案作为灵感。应该能够将该答案应用于 t2,然后再添加一条动态 sql 语句,通过将 t1 连接到您的旋转 t2 来获得最终输出。 (stackoverflow.com/questions/37468417/…)

标签: sql sql-server tsql join


【解决方案1】:

这是一个完整的脚本。我知道它可能不如上面那个简洁,但它不需要任何额外的附加组件就可以工作,而且也很容易解释。

我唯一不确定的是您是否需要三个单独的注释列或一列包含串联注释。我使用了连接注释方法......

declare @t1 table
(
    ID int not null,
    Name varchar(50),
    birthday date
)
declare @t2 table
(
    ID int not null,
    Note nvarchar(max)
)
insert into @t1
values
(2, 'Peter', '11/20/1990')
insert into @t1
values
(3, 'David', '12/22/1962')
insert into @t1
values
(4, 'Anna', '5/07/1992')
insert into @t2
values
(2, 'deciding')
insert into @t2
values
(2, 'purchased')
insert into @t2
values
(3, 'Presentation scheduled')
insert into @t2
values
(3, 'Presentation completed')
insert into @t2
values
(3, 'Purchased')
insert into @t2
values
(4, 'Ignored')

--Create table of all notes and what person they belong to.
declare @Notes table
(
    NoteID int not null,
    ID int not null,
    Note nvarchar(max)
)

--Insert into note table
insert into @Notes
(
    NoteID,
    ID,
    Note
)
SELECT ROW_NUMBER() OVER (ORDER BY t2.note),
       t1.ID,
       Note
FROM @t1 as t1
    left outer join @t2 AS t2
        ON t1.ID = t2.ID

--Create a table of person ID and concatenated notes.
declare @ConcatNotes table
(
    ID int not null,
    Note nvarchar(max)
)

--Insert just people first
insert into @ConcatNotes
(
    ID
)
select distinct
    ID
FROM @Notes

declare @NoteCount int
declare @i int = 1

select @NoteCount = max(noteid)
from @Notes

--While loop to loop through ALL notes by person ID and concatenate with semicolon. Change semicolon to whatever you want.
while (@i <= @NoteCount)
BEGIN
    update a
    set Note = isnull(a.Note + ';', '') + b.Note
    --select *
    from @ConcatNotes a
        inner join @Notes b
            on a.id = b.ID
    where b.Noteid = @i
    set @i = @i + 1
END

--A select to show the person ID and the concatenated notes.
select *
from @ConcatNotes

--The final query you were looking for.
select a.*,
       b.Note
from @t1 a
    inner join @ConcatNotes b
        on a.ID = b.ID

【讨论】:

  • 非常感谢您的帮助,我更喜​​欢在不同的列上做笔记,例如 note1 column = row number 1 , note2 column = row number 2。但根据您的查询,我可以完成。但是,我已经了解了透视表,这可能是解决我的情况的最佳方法,但我对此知之甚少,需要研究以了解如何将透视表应用于这种情况。总的来说,这个答案给了我想要的结果。我真的很感谢你的时间。
【解决方案2】:

我在这里找到了这个 CLR 解决方案: https://groupconcat.codeplex.com 并成功使用。

基本上,您的查询将变为:

;WITH example AS (
SELECT t1.id, t1.Name, t1.birthday, t2.id AS t2id, t2.Note 
        , ROW_NUMBER() OVER (PARTITION BY t1.ID ORDER BY t2.id) AS 'ROW NUMBER'
FROM @t1 as t1
left outer join @t2 AS t2 ON t1.ID = t2.ID 
)
select ID, name, birthday, [dbo].[GROUP_CONCAT_D]( Note, '   -') AS Notes
from example
group by ID, name, birthday

结果如下所示:

ID  name    birthday    Notes
2   Peter   1990-11-20  deciding   -purchased
3   David   1962-12-22  Presentation scheduled   -Presentation completed   -Purchased
4   Anna    1992-05-07  Ignored

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2013-05-27
  • 2021-11-03
相关资源
最近更新 更多