3

我需要将数据从一个表传输到另一个表。第二个表有一个主键约束(第一个没有约束)。它们具有相同的结构。我想要的是从表 A 中选择所有行并将其插入表 B 中而没有重复的行(如果一行是重复的,我只想取我找到的第一个)

例子 :

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 包含不同的数据)。

我怎样才能通过一次选择来做到这一点?

谢谢

4

5 回答 5

4

首先,您需要定义是什么让一行成为“第一”。我将组成一个任意定义,您可以根据需要更改 SQL。对于此示例,我假设“first”是 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,那么您也需要考虑这一点。

于 2009-02-10T01:22:15.937 回答
3

不确定您如何知道新表中需要第 2 行和第 3 行中的哪一个,但在 mysql 中您可以简单地:

insert ignore into new_table (select * from old_table);

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

于 2009-02-10T00:52:35.523 回答
2

你的数据库是什么?在甲骨文你可以说

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

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

于 2009-02-10T00:46:11.500 回答
1

这取决于你在寻找什么。

JOIN使用+ WHERE NULLNOT IN和之间有很大的不同NOT EXISTS,包括性能,这对于更大的数据集更为重要。

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

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

于 2012-01-11T22:12:21.533 回答
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

或者

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))
于 2009-02-10T09:04:37.760 回答