Sql server 如何比较同一SQL表的多行
假设我有一个SQL Server表,如下所示:Sql server 如何比较同一SQL表的多行,sql-server,Sql Server,假设我有一个SQL Server表,如下所示: id valA valB valC ----------------------- 1 1 2 3 2 4 5 6 3 7 8 9 3 10 11 12 4 13 14 15 4 16 14 15 select * from ( select t.*,
id valA valB valC
-----------------------
1 1 2 3
2 4 5 6
3 7 8 9
3 10 11 12
4 13 14 15
4 16 14 15
select
*
from (
select
t.*,
count(*) over (partition by id, valb, valc) cnt
from t
) t where cnt > 1;
我想比较行,找出那些数据匹配的行。在本例中,我希望标识具有匹配id、valB和valC的行,因此它应该只找到最后两行。valA列的内容将被忽略
然后我想删除两行中的一行,然后根据需要调整valA列。我的问题是识别匹配的行
从这个网站上的许多其他类似问题中,我尝试了各种类似的方法:
SELECT DISTINCT
A.id
FROM
newtable A
INNER JOIN
newtable B ON A.id = B.id
WHERE
A.valB = B.valB AND
A.valC = B.valC
但我最终得到了四个身份证。我不知道为什么。即使这样做有效,我仍然不确定如何继续对找到的所有匹配行执行更新和删除操作。有什么建议吗?谢谢。我想你很接近了。您只需排除不需要的行:
SELECT DISTINCT A.id
FROM newtable A INNER JOIN
newtable B
ON A.id = B.id
WHERE A.valB = B.valB AND
A.valC = B.valC AND
A.valA <> B.valA;
选择不同的A.id
从newtable到内部联接
新表B
在A.id=B.id上
其中A.valB=B.valB和
A.valC=B.valC和
A.valA B.valA;
您也可以使用。如果您有这些类型的查询,许多索引HASHBYTES
列将有助于比较
或者你可以用DenseRank
;With cte
as
(
select *,
dense_rank() over ( order by id,valb,valc) as rownum
from #temp
)
select * from cte where rownum>1
如果您只需要至少有两行具有相同valb和valc的id,您可以使用:
select distinct
id
from t
group by
id, valb, valc
having count(*) > 1;
;with x as (
select *, count(*) over (partition by id, valb, valc) as N from YourTable
)
-- matching values
select x.id, x.vala, x.valb, x.valc from x where x.N > 1
如果还需要获取其他列,可以使用如下窗口函数count
:
id valA valB valC
-----------------------
1 1 2 3
2 4 5 6
3 7 8 9
3 10 11 12
4 13 14 15
4 16 14 15
select
*
from (
select
t.*,
count(*) over (partition by id, valb, valc) cnt
from t
) t where cnt > 1;
。。。我的问题是识别匹配的行
要选择匹配的行,请使用以下命令:
select distinct
id
from t
group by
id, valb, valc
having count(*) > 1;
;with x as (
select *, count(*) over (partition by id, valb, valc) as N from YourTable
)
-- matching values
select x.id, x.vala, x.valb, x.valc from x where x.N > 1
…我仍然不确定如何继续更新和删除操作
我建议先做一个选择,然后再查看要删除的内容
小提琴选择比赛: 从以下位置删除: 包括原始表中记录的行号(按Id排序):
告诉你的需求lil更多,比如你将通过什么参数等等 你可以试试这个
declare @t table(id int,valA int,valB int,valC int)
insert into @t values
(1 , 1 , 2 , 3 )
,(2 , 4 , 5 , 6 )
,(3 , 7 , 8 , 9 )
,(3 , 10 , 11 , 12)
,(4 , 13 , 14 , 15)
,(4 , 16 , 14 , 15)
;With CTE as
(
select * ,row_number()over(partition by id,valb,valc order by id)rn
from @t
)
,CTE1 as
(
select * from cte
where rn>1
)
select * from @t t
where EXISTS(
select id from cte1 c where t.id=c.id)
谢谢,好主意。MSSQL在第一个示例中抱怨CONCAT。第二个示例运行了,但生成了整个表,只是按id排序。谢谢,我现在理解了为什么所有行都出现了,因为它正在查找给定行和另一个(相同)表中的同一行之间的匹配。添加现有内容的问题是,valA内容有时可能会匹配。我想我可以通过在表中有一个唯一的id字段来解决这个问题。@AngeloQ。是的,一个唯一的id可以解决我在
valA
上通过比较试图解决的问题。第一个关于group的示例是一个好主意,只要SELECT包含group BY中的列,否则它会给我一个错误。不过,我也许可以处理这个问题。第二个示例对我不起作用,可能是语法错误?我试图修复它,但无法。谢谢,这似乎对我最有效。不过,我从MSSQL Server 2005中得到了这个错误:“不支持OVER SQL构造或语句。”但它仍然运行,似乎给出了预期的结果。另外,我如何获取行号,或者用什么其他方法最容易返回到原始表中的该行。事实上,我发现我不能简单地删除第二行,直到我第一次将这两行合并在一起。在删除第二行之前,我需要检查valA(和其他列)的内容并复制值。您将传递什么参数?