我有成千上万的序列号记录。由于记录保存不佳,其中许多都在其他记录中重复。
我们正在使用这些记录做一些事情,但我们只希望在新表中记录具有唯一序列号的记录。所以重复的行应该被忽略,我们稍后会处理重复的行。
(原始表也没有主键列,这就是我们在临时表中注入的原因)
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等等尝试不同的东西,但我似乎无法得到我想要的结果。
似乎有很多方法可以找到重复项,但很难找到忽略它们的方法。
答案 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
并只是在索引中查找一个值 - 这非常快。很难想到更快的潜在执行计划。