Sql 如何通过添加溢出列来消除id列的重复数据?
好了,伙计们,我需要帮助!我需要复制ID列,但我在添加列时遇到了问题,同时又没有丢失重要数据。 有没有一种方法可以创建一个溢出列,将次要的[tags]放入一个新列中 以下是一个例子:Sql 如何通过添加溢出列来消除id列的重复数据?,sql,sql-server,tsql,duplicates,Sql,Sql Server,Tsql,Duplicates,好了,伙计们,我需要帮助!我需要复制ID列,但我在添加列时遇到了问题,同时又没有丢失重要数据。 有没有一种方法可以创建一个溢出列,将次要的[tags]放入一个新列中 以下是一个例子: **UniqueId** **Age** **Zip*** **Tag** 1 20 11111 yellow 2
**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
非常感谢您的帮助 如果您现在选择了最大标记数,则可以使用pivot或conditional aggregation:
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;
如果您现在选择了最大标记数,则可以使用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;
虽然我倾向于Gordon所说明的条件聚合。。。它们提供了更多的灵活性 你可以做一个简单的旋转 范例 返回
虽然我倾向于Gordon所说明的条件聚合。。。它们提供了更多的灵活性 你可以做一个简单的旋转 范例 返回 注意:不要将年龄存储为整数!而是存储一个DOB并计算年龄 这不是你问题的真正答案,而是你应该做的事情: 老实说:你的问题可以解决,而且已经有了很好的答案,但你不应该这样做。 每当您觉得需要在字段名称Tag1、Tag2中添加数字时。。。这种设计几乎永远都是错误的。将这些值推入相关的边表(仅Id和标记),从原始表中删除列,并放置一个指向新表的外键。现在,您可以随时连接这些值。数据透视或条件聚合仅用于输出 这是完全未经测试的,因此请小心您的数据备份!,但是,按照这些思路应该可以做到:
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;
如果您需要这些数据透视列,您也可以使用其他答案中提供的方法进行最终选择。注意:不要将年龄存储为整数!而是存储一个DOB并计算年龄
这不是你问题的真正答案,而是你应该做的事情:
老实说:你的问题可以解决,而且已经有了很好的答案,但你不应该这样做。
每当您觉得需要在字段名称Tag1、Tag2中添加数字时。。。这种设计几乎永远都是错误的。将这些值推入相关的边表(仅Id和标记),从原始表中删除列,并放置一个指向新表的外键。现在,您可以随时连接这些值。数据透视或条件聚合仅用于输出
这是完全未经测试的,因此请小心您的数据备份!,但是,按照这些思路应该可以做到:
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;
如果您需要这些数据透视列,也可以使用其他答案中提供的方法进行最终选择。如果只有3个重复项的更改,则可以使用窗口函数和聚合,否则我将使用动态数据透视。你能具体说明一下吗?注意,如果是N个重复,那么你可以在谷歌上搜索动态透视,并在几个小时前找到大量的示例:如果只有3个重复,那么你可以使用窗口函数和聚合,否则我将使用动态透视。你能具体说明一下吗?请注意,如果是N个重复的,那么您可以在google dynamic pivot上搜索数吨的示例数(就在几个小时前):完全掩盖了年龄。大眼睛。完全掩盖了年龄的一点。大眼睛。