2009-02-10 43 views
3

我需要将数据从一个表传输到另一个表。第二个表有一个主键约束(第一个表没有约束)。它们具有相同的结构。我想是从表A中选择所有的行和表B中没有重复的行插入它(如果行IS0重复,我只想把我第一个发现)SQL - 仅选择不重复的行

例子:

MyField1 (PK) | MyField2 (PK) | MyField3(PK) | MyField4 | MyField5 

---------- 

1    | 'Test'   | 'A1'   | 'Data1' | 'Data1' 
2    | 'Test1'   | 'A2'   | 'Data2' | 'Data2' 
2    | 'Test1'   | 'A2'   | 'Data3' | 'Data3' 
4    | 'Test2'   | 'A3'   | 'Data4' | 'Data4' 

就像你所看到的,第二行和第三行获得了相同的PK键,但MyField4和MyField5中的数据不同。所以,在这个例子中,我想要第一,第二和第四行。不是第三个,因为它是第二个的重复(即使MyField4和MyField5包含不同的数据)。

我怎样才能做到这一点单选?

thx

+0

MySql,Oracle,MS Sql或其他? – BenMaddox 2009-02-10 00:52:44

回答

4

首先,您需要定义是什么使行成为“第一”。我将构建一个任意的定义,并且您可以根据需要更改SQL以满足您的需求。对于这个例子,我假设“首先”是MyField4的最低值,如果它们相等,那么MyField5的最低值。它也说明了所有5列相同的可能性。

SELECT DISTINCT 
    T1.MyField1, 
    T1.MyField2, 
    T1.MyField3, 
    T1.MyField4, 
    T1.MyField5 
FROM 
    MyTable T1 
LEFT OUTER JOIN MyTable T2 ON 
    T2.MyField1 = T1.MyField1 AND 
    T2.MyField2 = T1.MyField2 AND 
    T2.MyField3 = T1.MyField3 AND 
    (
      T2.MyField4 > T1.MyField4 OR 
      (
       T2.MyField4 = T1.MyField4 AND 
       T2.MyField5 > T1.MyField5 
     ) 
    ) 
WHERE 
    T2.MyField1 IS NULL 

如果你也想占未在源表中重复的PK,而是已经存在于你的目标表,那么你就需要考虑这一点。

2

什么是您的数据库?在Oracle中,您可以说

SELECT FROM your_table 
WHERE rowid in 
(SELECT MIN(rowid) 
FROM your_table 
GROUP BY MyField1, MyField2, MyField3); 

请注意,具有相同PK的哪些行将被视为“第一个”是有些不确定的。如果您需要强制执行特定的订单,则需要另外对其他列进行排序。

+0

这会为your_table中的每一行运行一次嵌套的select语句吗?如果可以的话,那么你的表现会非常糟糕。 希望嵌套语句可以被缓存。不熟悉它的查询计划部分。 – Bassam 2009-02-10 01:20:46

+0

我使用MS SQL 2005,但我认为这个语法会起作用,我会明天再试,然后我会通知你。谢谢! – Melursus 2009-02-10 01:22:20

3

不知道你是怎么知道哪一行2和第3行,你在新表中想要的,但在MySQL中,你可以简单地说:

insert ignore into new_table (select * from old_table); 

而且PK不会允许插入重复的条目。

0
CREATE TABLE #A(
ID INTEGER IDENTITY, 
[MyField1] [int] NULL, 
[MyField2] [varchar](10) NULL, 
[MyField3] [varchar](10) NULL, 
[MyField4] [varchar](10) NULL, 
[MyField5] [varchar](10) NULL 
) 

INSERT INTO #A (MyField1,MyField2,MyField3,MyField4,MyField5) SELECT * FROM A 

insert into B 
    select MyField1,MyField2,MyField3,MyField4,MyField5 from #A a1 
    where not exists (select id from #A a2 where a2.MyField1 = a1.MyField1 and a2.ID < a1.ID) 

DROP TABLE #A 

OR

insert into b 
    select distinct * from a a1 
    where not exists (
    select a2.MyField1 from a a2 where a1.MyField1 = a2.MyField1 and 
     (a1.MyField2 < a2.MyField2 or a1.MyField3 < a2.MyField3 
     or a1.MyField4 < a2.MyField5 or a1.MyField5 < a2.MyField5)) 
1

这取决于你在找什么。

有使用JOIN + WHERE NULLNOT INNOT EXISTS,包括性能,这是更大的数据集更重要的一个很大的区别。

(参见NOT IN vs. NOT EXISTS vs. LEFT JOIN/IS NULL。)

链接本文中显示的三种方法是非常简单的。