繁体   English   中英

如何清除在SQL Server 2008中违反主键的数据?

How do I clean up data that would violate a Primary Key in SQL Server 2008?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我从无法控制的来源中获取了一些糟糕的数据,它需要进入一个带有复合主键的表,如下所示:

PK_Part1, PK_Part2, StringData, DateData

我糟糕的数据具有完全重复项,具有不同StringData的PK重复项,具有不同DateData的PK重复项,以及具有不同StringData和DateData的PK重复项。

所以我可能会看到:

1234,1234,Blah,2011-1-1
1234,1234,Blah,2011-1-1
4321,4321,Blah,2011-1-1
4321,4321,Blah,2011-10-10
5678,5678,Blah,2011-1-1
5678,5678,Blah1,2011-1-1
8765,8765,Blah,2011-1-1
8765,8765,Blah,2011-10-10
8765,8765,Blah1,2011-10-10

如何在SQL Server 2008中进行清理? 鉴于:
A)我只想要与最新日期关联的数据
B)我正在尝试强制有关字符串数据的来源问题,但就目前而言,更好的字符串是更好的,同样的长度也可以。
C)我必须假设源没有帮助,现在加载所有内容

我曾希望使用MERGE但是它似乎在执行任何“ MATCH”或“ NO MATCH”语句之前先比较Source表和Target表的所有行,因此我遇到了PK违例,并删除了PK约束,让所有重复项都在。

4 个回复

如果您在SQL Server中还没有该数据: BULK INSERT到临时表中:

CREATE TABLE #tempStaging
(PK_Part1 INT, PK_Part2 INT, StringData VARCHAR(500), DateData DATE)

BULK INSERT #tempStaging
FROM 'c:\yourfile.txt'
WITH (FIELDTERMINATOR =',',
     ROWTERMINATOR ='\n')

然后,您应该可以执行以下操作:

;WITH CleaupData AS
(
  SELECT 
      PK_Part1, PK_Part2, StringData, DateData,
      ROW_NUMBER() OVER(PARTIION BY PK_Part1, PK_Part2
                        ORDER BY DateData DESC, LEN(StringData) DESC) as 'RowNum'
  FROM
      #tempStaging
)
INSERT INTO dbo.YourTargetTable(PK_Part1, PK_Part2, StringData, DateData)
    SELECT PK_Part1, PK_Part2, StringData, DateData 
    FROM CleanupData
    WHERE RowNum = 1

这将根据某些条件(某些ID或某些名称)对数据进行“分区”,并且每个数据分区均按日期排序(降序-最新)。

因此, RowNum = 1的条目是每个分区的最新条目-选择该分区并扔掉所有其他分区,然后清除您的数据!

提示:这假设您的目标表为空! 如果不是这种情况,那么可以-您可能需要基于CTE来选择MERGE语句,该CTE从BULK INSERT中选择要保留的数据。

来自源的数据应该进入一个临时表,即一个临时温度区域。 然后,您可以从中选择最好的一个(因为样本数据即使在输入数据中也包含重复的part1 + part2)

样品表和温度表

create table pkdup(
    PK_Part1 int, PK_Part2 int, StringData varchar(100), DateData datetime,
    primary key (PK_Part1,PK_Part2))
insert pkdup select 1234,1234,'', GETDATE()+1000

create table #tmp(col1 nvarchar(max), col2 nvarchar(max), col3 nvarchar(max), col4 datetime)
insert #tmp values
(1234,1234,'Blah','2011-1-1'),
(1234,1234,'Blah','2011-1-1'),
(4321,4321,'Blah','2011-1-1'),
(4321,4321,'Blah','2011-10-10'),
(5678,5678,'Blah','2011-1-1'),
(5678,5678,'Blah1','2011-1-1'),
(8765,8765,'Blah','2011-1-1'),
(8765,8765,'Blah','2011-10-10'),
(8765,8765,'Blah1','2011-10-10');

合并语句

merge pkdup as target
using (
    select col1, col2, col3, col4
    from (select *, row_number() over (
        partition by col1, col2
        order by col4 desc, len(col3) desc) rownum
        from #tmp) t
    where rownum=1 -- only the best
    ) as source
on source.col1=target.PK_Part1 and source.col2=target.PK_Part2
WHEN MATCHED AND (source.col4 > target.datedata or (source.col4=target.datedata and len(source.col3) > target.stringdata))
    THEN UPDATE SET target.stringdata = source.col3, target.datedata = source.col4
WHEN NOT MATCHED THEN
    INSERT (PK_Part1, PK_Part2, StringData, DateData)
    VALUES (source.col1, source.col2, source.col3, source.col4);

我们通常将此类数据放入登台表中,然后在尝试运行merge语句之前清除登台表中的重复项。

不知道是否可以在联接中应用字符串长度函数,但是如果可以,请尝试以下操作:

select PK_Part1, PK_Part2, max_date, max_len, first(StringData) as first_string
from        
   (select PK_Part1, PK_Part2, max_date, max(len(StringData)) as max_len
    from table inner join
           (select PK_Part1, PK_Part2, max(DateData) as max_date
           from table
           group by
           PK_Part1, PK_Part2) md
    on table.PK_Part1 = md.PK_Part1 and 
           table.PK_Part2 = md.PK_Part2 and 
           table.DateData = md.max_date
    group by
           PK_Part1, PK_Part2, max_date) ml
   inner join table on 
           table.PK_Part1 = ml.PK_Part1 and 
           table.PK_Part2 = ml.PK_Part2 and 
           table.DateData = ml.max_date and
           len(table.StringData) = ml.max_len
   group by
           PK_Part1, PK_Part2, max_date, max_len
1 与Azure同步时如何不违反此主键?

项目总结 我们正在创建一个“数字”厨房,可以在冰箱,冰柜等中添加哪些物品。然后可以在Web应用程序上查看这些物品,因此您可以随时随地了解厨房中的杂货。 数据库 总共有三个表。 清单 它包含ListID和这些列表的名称,例如“ Fridge”或“ Freezer”。 ...

6 清理以提高SQL Server 2008中的性能

我是SQL Server的新手,很抱歉是一个非常基本的问题。 我正在监视每天要插入数据的一个表,正在使用sp_spaceused SP进行监视。以下是表中使用的空间摘要: 我想清除此表中的数据以提高性能。现在我将如何知道我可以在表中插入多少数据(在表中插入数据没有限制)? 多少天 ...

7 我该如何清理它?

我正在使用一个使用Google Weather API的应用程序,现在我得到了一些真正丑陋的代码,只是为了填充3天的预测,看起来就是这样(记得不笑) 我告诉过你这很难看。 我想要做的是有一个循环(和可能的泛型)来完成与这个丑陋的代码相同的任务。 我尝试了几种不同的方法,但总是失败。 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM