如何通过添加溢出列来重复数据删除列?

时间:2018-04-18 21:14:16

标签: sql sql-server tsql duplicates

好吧,我需要一些帮助!我需要复制ID列,我在添加列时遇到问题,而不会丢失重要数据。 有没有办法制作一个"overflow column"来接受辅助[tags]并将它们放入新列?

以下是示例:

 **UniqueId**           **Age**     **Zip***              **Tag**
    1                      20          11111               yellow
    2                      25          33333                blue
    2                      25          33333               black
    3                      30          44444               purple
    3                      30          44444                pink
    3                      30          44444                white

这就是我希望输出看起来像

  **UniqueId**          **Age**     **Zip***    **Tag1**  **Tag2**  **Tag3**
    1                      20          11111      yellow     NULL      NULL
    2                      25          33333       blue      black     NULL
    3                      30          44444      purple     pink     white

非常感谢您的帮助!!!

3 个答案:

答案 0 :(得分:4)

如果您现在是最大标记数,则可以使用pivot或条件聚合:

select t.uniqueid, t.age, t.zip,
       max(case when seqnum = 1 then tag end) as tag_1,
       max(case when seqnum = 2 then tag end) as tag_2,
       max(case when seqnum = 3 then tag end) as tag_2
from (select t.*,
             row_number() over (partition by uniqueid order by (select null)) as seqnum
      from t
     ) t
group by t.uniqueid, t.age, t.zip;

答案 1 :(得分:4)

虽然我倾向于喜欢条件聚合,正如戈登所说......他们提供了更多的灵活性。

你可以做一个简单的PIVOT

示例

Select *
 From  (
        Select UniqueID
              ,Age
              ,Zip
              ,Tag
              ,Col = concat('Tag',Row_Number() over (Partition By UniqueId order by Tag) )
         From YourTable
       ) A 
 Pivot (Max(Tag) for Col in ([Tag1],[Tag2],[Tag3],[Tag4]) ) p

<强>返回

UniqueID    Age Zip     Tag1    Tag2    Tag3    Tag4
1           20  11111   yellow  NULL    NULL    NULL
2           25  33333   black   blue    NULL    NULL
3           30  44444   pink    purple  white   NULL

答案 2 :(得分:1)

注意:不要将年龄存储为int号!而是存储DOB并计算年龄......

这不是你问题的真实答案,而是你应该做的事情:

说实话:你的问题可以解决(并且已经有了很好的答案),但你不应该这样做 每当您觉得需要在字段的名称(Tag1,Tag2 ......)中添加数字时,设计就会出错(几乎所有)。将这些值推送到相关的边表(只是Id和标记),从原始表中删除列并放置指向新表的外键。现在,您可以在需要时加入这些值。 PIVOT(或条件聚合)仅用于输出...

这是完全未经测试的,所以要小心你的数据(备份!),但这些内容应该有效:

CREATE TABLE TagTable (ID INT IDENTITY
                      ,FKOriginal INT NOT NULL CONSTRAINT FK_TagTable_OriginalTable FOREIGN KEY REFERENCES OriginalTable(UniqueId)
                      ,Tag VARCHAR(100) NOT NULL);

--an index to support the fk
CREATE NONCLUSTERED INDEX IX_TagTable_FKOriginal ON TagTable(FKOriginal);
GO

--shift the existing data
INSERT INTO TagTable --you might use DISTINCT...
SELECT UniqueId,Tag
FROM OriginalTable;
GO

--delete duplicated rows
WITH cte AS
(
    SELECT *
          ,ROW_NUMBER() OVER(PARTITION BY UniqueId ORDER BY UniqueId) AS RowId --Find a better sort column if needed
    FROM OriginalTable 
)
DELETE FROM cte
WHERE RowId>1; --Only the first remains
GO

--throw away the tag column in the original table
ALTER TABLE OriginalTable DROP COLUMN Tag;
GO

--See the result via JOIN-Select
SELECT *
FROM OriginalTable AS o
INNER JOIN TagTable AS t ON o.UniqueId=t.FKOriginal;

如果您需要这些透视列,您也可以使用其他答案中提供的方法与最终SELECT