将行插入临时表,其中列没有重复值

时间:2018-04-23 08:22:08

标签: sql sql-server tsql

我有成千上万的序列号记录。由于记录保存不佳,其中许多都在其他记录中重复。

我们正在使用这些记录做一些事情,但我们只希望在新表中记录具有唯一序列号的记录。所以重复的行应该被忽略,我们稍后会处理重复的行。

(原始表也没有主键列,这就是我们在临时表中注入的原因)

declare @total int = 603578;
declare @cnt int = 1;

create table #Temp
(
  Id int IDENTITY(1,1),
  FirstName nvarchar(30), 
  LastName nvarchar(30),
  SerialNumber varchar(254),
  ...
)

while @cnt < @total
insert into #Temp SELECT * FROM electronic_list;

我希望能够添加一些简单的东西:

where SerialNumber is unique

where SerialNumber is distinct

但它似乎并不那么简单。我尝试使用select distinct,select count with group by和having等等尝试不同的东西,但我似乎无法得到我想要的结果。

似乎有很多方法可以找到重复项,但很难找到忽略它们的方法。

4 个答案:

答案 0 :(得分:4)

为什么不使用 window 功能?

select * from (
     select *, 
           count(SerialNumber) over (partition by SerialNumber) Counts 
     from electronic_list
) t
where Counts = @cnt;

但是,这只会选择SerialNumber只有@cnt参数建议的1条记录。

答案 1 :(得分:3)

您可以GROUP数据,INSERT只有HAVING COUNT(*) = 1个单项的行serialNumber ------------- DUPED DUPED UNIQUE DISTINCT ANOTHERDUPE ANOTHERDUPE ANOTHER_UNIQUE 。下面是一些可以在下面的虚拟数据上运行的示例代码:

CREATE TABLE #serials
    (
        id INT IDENTITY(1, 1) ,
        serialNumber NVARCHAR(254)
    );

CREATE TABLE #electronic_list
    (
        serialNumber NVARCHAR(254)
    );

INSERT INTO #electronic_list ( serialNumber )
VALUES ( N'DUPED' ) ,
       ( N'DUPED' ) ,
       ( N'UNIQUE' ) ,
       ( N'DISTINCT' ) ,
       ( N'ANOTHERDUPE' ) ,
       ( N'ANOTHERDUPE' ) ,
       ( N'ANOTHER_UNIQUE' );

-- SELECT *
-- FROM   #electronic_list AS el;

INSERT INTO #serials ( serialNumber )
            SELECT   serialNumber
            FROM     #electronic_list AS el
            GROUP BY el.serialNumber
            HAVING   COUNT(el.serialNumber) = 1;

SELECT *
FROM   #serials AS s;

DROP TABLE #electronic_list;
DROP TABLE #serials;

完整的例子:

id          serialNumber
----------- ---------------
1           ANOTHER_UNIQUE
2           DISTINCT
3           UNIQUE

产地:

{{1}}

您只需要扩展代码以插入其他列中的数据。

答案 2 :(得分:0)

另一种方法是foreach (var pItem in pNodes) { ParentAttribute pAtt = new ParentAttribute(); pAtt.parentNodeValue = pItem["Attribute"].ToString(); pAtt.id = Convert.ToInt32(pItem["ID"]); pAtt.ChildNodeValues = new List<ChildAttribute>(); var cNodes = (from cRow in dt.AsEnumerable() where cRow.Field<decimal?>("Parent_Id") == pAtt.id select cRow).ToList(); foreach (var cItem in cNodes) { ChildAttribute cAtt = new ChildAttribute(); // May be another foreach required here cAtt.childNodeValue = cItem["Attribute"].ToString(); cAtt.sequence = Convert.ToInt32(!cItem.IsNull("Sequence")); cAtt.parentId = Convert.ToInt32(!cItem.IsNull("Parent_Id")); pAtt.ChildNodeValues.Add(cAtt); } att.ParentNodes.Add(pAtt); } 虽然它已经使用CTE完成,所以只是试图展示更多的选择,这可能是有效的

subquery

答案 3 :(得分:0)

虽然窗口函数是一种简单的方法,但效率最高的可能是not exists

select t.*
from #test t
where not exists (select 1 from #test t2 where t2.SerialNumber = t.SerialNumber and t2.id <> t.id);

为了提高性能,您需要#test(SerialNumber, id)上的索引。

这个更快,因为基本上你正在扫描#test1并只是在索引中查找一个值 - 这非常快。很难想到更快的潜在执行计划。