Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用SQL查找和更新重复行的第一行_Sql_Sql Server - Fatal编程技术网

如何使用SQL查找和更新重复行的第一行

如何使用SQL查找和更新重复行的第一行,sql,sql-server,Sql,Sql Server,我正在寻找一种很好的方法来完成以下工作: 我们有一个表帐户,其中一些记录意外导入了两次,因此它们是重复的。我发现我可以通过以下查询选择导入两次的所有行: select name, vatnumber from Accounts WHERE IsDeleted='false' GROUP BY name, vatnumber HAVING count(*) > 1 基本上:如果名称和编号相同,则它们是重复的 这将提供所有已导入两次的记录。现在,我正在寻找一种方法来获取每个双记录的第一个I

我正在寻找一种很好的方法来完成以下工作:

我们有一个表帐户,其中一些记录意外导入了两次,因此它们是重复的。我发现我可以通过以下查询选择导入两次的所有行:

select name, vatnumber from Accounts 
WHERE IsDeleted='false'
GROUP BY name, vatnumber
HAVING count(*) > 1
基本上:如果名称和编号相同,则它们是重复的

这将提供所有已导入两次的记录。现在,我正在寻找一种方法来获取每个双记录的第一个Id,以便我可以执行以下操作:

UPDATE Accounts SET IsDeleted='true'
WHERE Id = (select id ...) 
所以基本上,我正在尝试更新每一条双打记录的第一行,这样就没有更多的双打了。谁能给我指一下正确的方向吗?除了做体力劳动之外,我对如何开始做这件事一无所知,我猜有一个更简单的方法

样本数据:

Id     VatNumber     Name
 1     BE10128292    Microsoft
 2     BE99292200    Google
 3     BE10128292    Microsoft
 4     BE99292200    Some other company
 5     BE99292200    Google
预期结果:

Id     VatNumber     Name
 1     BE10128292    Microsoft
 2     BE99292200    Google
不管我是第一张微软唱片还是最后一张微软唱片。理想情况下,这将是第一次

with  CTE  as
( 
select *,ROW_NUMBER()over(partition by vatnumber,name order by ID )rowid  
from #tableName
)
select * from CTE where rowid='2' // here you can change RowID 2 or 1

检查演示

这应该可以完成任务,运行示例并检查输出。它会在找到重复项的位置更新IsDeleted标志,但使用MINID仅针对第一行

CREATE TABLE #dupes
(
    id INT,
    vatNo NVARCHAR(20),
    name NVARCHAR(20),
    isDeleted BIT
        DEFAULT 0
);

INSERT INTO #dupes
(
    id,
    vatNo,
    name
)
VALUES
(1, 'BE10128292', 'Microsoft'),
(2, 'BE99292200', 'Google'),
(3, 'BE10128292', 'Microsoft'),
(4, 'BE99292200', 'Some other company'),
(5, 'BE99292200', 'Google');


UPDATE #dupes
SET isDeleted = 1
WHERE id IN (
                SELECT MIN(id) MinId
                FROM #dupes
                WHERE isDeleted = 0
                GROUP BY name,
                         vatNo
                HAVING COUNT(*) > 1
            );

SELECT *
FROM #dupes AS d;

DROP TABLE #dupes;
产生:

因此,针对您的数据库,查询将是:

UPDATE Accounts 
SET isDeleted = 1
WHERE Id IN (
                SELECT MIN(id) MinId
                FROM Accounts
                WHERE isDeleted = 0
                GROUP BY name,
                         vatNo
                HAVING COUNT(*) > 1
            );
使用CTE尝试以下操作:

请按以下方式尝试CTE:

WITH CTE
         AS (
         SELECT vatnumber,
                name,
                ROW_NUMBER() OVER(PARTITION BY vatnumber,
                                               name ORDER BY ID) rowid,
                IsDeleted
         FROM Accounts
         WHERE IsDeleted = 'false')
         UPDATE CTE
           SET
               IsDeleted = 'true'
         WHERE rowid > 1; 
试试这个

;WITH  removeDup  as

( 

SELECT *,ROW_NUMBER() OVER(PARTITION BY vatnumber,name ORDER BY ID ) DupId  

from Accounts

)

DELETE from removeDup where DupId=2 

更新了我的问题与样本数据和期望的输出可能重复的感谢!这就是我采用的解决方案!这是最好的解决办法。Good@Mr.Bhosale考虑到他要求更新查询,我不得不同意。
Id     VatNumber     Name
 1     BE10128292    Microsoft
 2     BE99292200    Google
WITH CTE
         AS (
         SELECT vatnumber,
                name,
                ROW_NUMBER() OVER(PARTITION BY vatnumber,
                                               name ORDER BY ID) rowid,
                IsDeleted
         FROM Accounts
         WHERE IsDeleted = 'false')
         UPDATE CTE
           SET
               IsDeleted = 'true'
         WHERE rowid > 1; 
;WITH  removeDup  as

( 

SELECT *,ROW_NUMBER() OVER(PARTITION BY vatnumber,name ORDER BY ID ) DupId  

from Accounts

)

DELETE from removeDup where DupId=2