Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.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 Server 2005-在保留第一条记录的同时删除重复记录_Sql_Tsql_Sql Server 2005 - Fatal编程技术网

SQL Server 2005-在保留第一条记录的同时删除重复记录

SQL Server 2005-在保留第一条记录的同时删除重复记录,sql,tsql,sql-server-2005,Sql,Tsql,Sql Server 2005,我目前正在编写一个DataImport脚本,用于将数据从一个数据库移动到另一个数据库。我遇到的主要问题是,该表包含大量重复记录,重复字段为产品代码、语言、法规、品牌名称、公式和版本,即数据库中可能有以下内容: 我的测试产品,英国英语,测试品牌,测试配方,1(ID 1-不包括在组别中) 我的测试产品,英国英语,测试品牌,测试配方,1(ID 2-不包括在组别中) 我的测试产品,英国英语,测试品牌,测试配方,1(ID 3-不包括在组别中) 我的测试产品,英国英语,测试品牌,测试配方,1(ID 4-不包

我目前正在编写一个DataImport脚本,用于将数据从一个数据库移动到另一个数据库。我遇到的主要问题是,该表包含大量重复记录,重复字段为产品代码、语言、法规、品牌名称、公式和版本,即数据库中可能有以下内容:

我的测试产品,英国英语,测试品牌,测试配方,1(ID 1-不包括在组别中)
我的测试产品,英国英语,测试品牌,测试配方,1(ID 2-不包括在组别中)
我的测试产品,英国英语,测试品牌,测试配方,1(ID 3-不包括在组别中)
我的测试产品,英国英语,测试品牌,测试配方,1(ID 4-不包括在组别中)

正如你所看到的,这些记录在各个方面都是相同的。我的问题是,作为数据加载脚本的一部分,我希望删除ID为1、2和3的记录,同时保留ID为4的记录,因为这将是最新的记录,因此也是我希望保留的记录。为此,我编写了一个T-SQL脚本,如下所示:

-- get the list of items where there is at least one duplicate
DECLARE cDuplicateList CURSOR FOR
SELECT productcode, languageid, legislationid, brandName, versionnumber, formulaid
FROM allproducts
GROUP BY productcode, languageid, legislationid, brandName, versionnumber, formulaid
HAVING COUNT (*) > 1  

OPEN cDuplicateList

FETCH cDuplicateList INTO @productCode, @languageId, @legislationId, @brandName, @versionNumber, @formulaId

-- while there are still duplicates
WHILE @@FETCH_STATUS=0
BEGIN

-- delete from the table where the product ID is in the sub-query, which contains all
-- of the records apart from the last one
DELETE FROM AllProducts 
WHERE productId IN
(
    SELECT productId
    FROM allProducts
    WHERE productCode = @productCode 
        AND (languageId = @languageId OR @languageId IS NULL) 
        AND (legislationId = @legislationId OR @legislationId IS NULL)
        AND (brandName = @brandName OR @brandName IS NULL)
        AND (versionNumber = @versionNumber OR @versionNumber IS NULL)
        AND (formulaId = @formulaId OR @formulaId IS NULL)
    EXCEPT
    SELECT TOP 1 productId
    FROM allProducts
    WHERE productCode = @productCode 
        AND (languageId = @languageId OR @languageId IS NULL) 
        AND (legislationId = @legislationId OR @legislationId IS NULL)
        AND (brandName = @brandName OR @brandName IS NULL)
        AND (versionNumber = @versionNumber OR @versionNumber IS NULL)
        AND (formulaId = @formulaId OR @formulaId IS NULL)
)

FETCH cDuplicateList INTO @productCode, @languageId, @legislationId, @brandName, @versionNumber, @formulaId

END

现在,这确实起作用了——它的速度太慢了,我想不出任何简单的方法让它更快。有人知道如何维护相同的功能,但使其运行更快吗?

您已经可以在SQL\u Server 2005中使用
通用表表达式和
行数

WITH CTE AS
(
    SELECT ProductCode, Language, Legislation, BrandName, Formula, Version,
       RN = ROW_NUMBER() 
                   OVER ( 
                     PARTITION BY productcode, language, legislation, brandname, formula, version 
                     ORDER BY id DESC) 
    FROM dbo.Students
)
DELETE FROM CTE WHERE RN > 1

如果您想查看要删除的内容,请将
DELETE
更改为
SELECT*

您已经可以在SQL\u Server 2005中使用
通用表表达式和
行数

WITH CTE AS
(
    SELECT ProductCode, Language, Legislation, BrandName, Formula, Version,
       RN = ROW_NUMBER() 
                   OVER ( 
                     PARTITION BY productcode, language, legislation, brandname, formula, version 
                     ORDER BY id DESC) 
    FROM dbo.Students
)
DELETE FROM CTE WHERE RN > 1

如果您想查看要删除的内容,请将
DELETE
更改为
SELECT*

您已经可以在SQL\u Server 2005中使用
通用表表达式和
行数

WITH CTE AS
(
    SELECT ProductCode, Language, Legislation, BrandName, Formula, Version,
       RN = ROW_NUMBER() 
                   OVER ( 
                     PARTITION BY productcode, language, legislation, brandname, formula, version 
                     ORDER BY id DESC) 
    FROM dbo.Students
)
DELETE FROM CTE WHERE RN > 1

如果您想查看要删除的内容,请将
DELETE
更改为
SELECT*

您已经可以在SQL\u Server 2005中使用
通用表表达式和
行数

WITH CTE AS
(
    SELECT ProductCode, Language, Legislation, BrandName, Formula, Version,
       RN = ROW_NUMBER() 
                   OVER ( 
                     PARTITION BY productcode, language, legislation, brandname, formula, version 
                     ORDER BY id DESC) 
    FROM dbo.Students
)
DELETE FROM CTE WHERE RN > 1
如果您想查看要删除的内容,请将
DELETE
更改为
SELECT*

您可以使用行号()覆盖(按productcode、languageid、LegirationId、brandName、versionnumber、formulaid按productId描述排序) 并删除行号大于1的所有ProducitID

您可以在上面使用行号()(按productcode、languageid、LegirationID、brandName、versionnumber、formulaid顺序按productId描述划分) 并删除行号大于1的所有ProducitID

您可以在上面使用行号()(按productcode、languageid、LegirationID、brandName、versionnumber、formulaid顺序按productId描述划分) 并删除行号大于1的所有ProducitID

您可以在上面使用行号()(按productcode、languageid、LegirationID、brandName、versionnumber、formulaid顺序按productId描述划分)
并删除行号大于1的所有ProducitID,前提是您的productId列是唯一的ID:

delete  p1
from    AllProducts p1
join    AllProducts p2
on      p1.languageId = p2.languageId
and     p1.legislationId = p2.legislationId
and     p1.brandName = p2.brandName
and     p1.versionNumber = p2.versionNumber
and     p1.formulaId = p2.formulaId
and     p1.productId < p2.productId
删除p1
来自所有产品p1
加入所有产品p2
在p1.languageId=p2.languageId上
p1.legictionId=p2.legictionId
p1.brandName=p2.brandName
p1.versionNumber=p2.versionNumber
p1.formulaId=p2.formulaId
p1.productId
这将删除所有存在匹配项的最新记录


如果要删除符合某些条件(例如,仅限品牌名称和版本号)的记录,请从联接中删除其他子句。

假设productId列是唯一ID:

delete  p1
from    AllProducts p1
join    AllProducts p2
on      p1.languageId = p2.languageId
and     p1.legislationId = p2.legislationId
and     p1.brandName = p2.brandName
and     p1.versionNumber = p2.versionNumber
and     p1.formulaId = p2.formulaId
and     p1.productId < p2.productId
删除p1
来自所有产品p1
加入所有产品p2
在p1.languageId=p2.languageId上
p1.legictionId=p2.legictionId
p1.brandName=p2.brandName
p1.versionNumber=p2.versionNumber
p1.formulaId=p2.formulaId
p1.productId
这将删除所有存在匹配项的最新记录


如果要删除符合某些条件(例如,仅限品牌名称和版本号)的记录,请从联接中删除其他子句。

假设productId列是唯一ID:

delete  p1
from    AllProducts p1
join    AllProducts p2
on      p1.languageId = p2.languageId
and     p1.legislationId = p2.legislationId
and     p1.brandName = p2.brandName
and     p1.versionNumber = p2.versionNumber
and     p1.formulaId = p2.formulaId
and     p1.productId < p2.productId
删除p1
来自所有产品p1
加入所有产品p2
在p1.languageId=p2.languageId上
p1.legictionId=p2.legictionId
p1.brandName=p2.brandName
p1.versionNumber=p2.versionNumber
p1.formulaId=p2.formulaId
p1.productId
这将删除所有存在匹配项的最新记录


如果要删除符合某些条件(例如,仅限品牌名称和版本号)的记录,请从联接中删除其他子句。

假设productId列是唯一ID:

delete  p1
from    AllProducts p1
join    AllProducts p2
on      p1.languageId = p2.languageId
and     p1.legislationId = p2.legislationId
and     p1.brandName = p2.brandName
and     p1.versionNumber = p2.versionNumber
and     p1.formulaId = p2.formulaId
and     p1.productId < p2.productId
删除p1
来自所有产品p1
加入所有产品p2
在p1.languageId=p2.languageId上
p1.legictionId=p2.legictionId
p1.brandName=p2.brandName
p1.versionNumber=p2.versionNumber
p1.formulaId=p2.formulaId
p1.productId
这将删除所有存在匹配项的最新记录

如果要删除符合某些条件(例如,仅限品牌名称和版本号)的记录,请从联接中删除其他子句。

可能重复的可能重复的可能重复的可能重复的