将行从一个表复制到另一个表,忽略重复

时间:2009-03-17 21:05:48

标签: sql tsql

我有2个表(srcTable1& destTable),它们具有相同的模式。我试图将所有行从srcTable复制到destTable并忽略重复项。我以为我可以添加一个带有子查询的WHERE子句,该子查询只给出不重复的行。但是,它似乎不起作用。我没有插入或选择任何行。

INSERT INTO destTable
SELECT * FROM srcTable
WHERE NOT EXISTS(SELECT * FROM destTable)

我意识到我可以做这样的事情:

INSERT INTO destTable
SELECT * FROM srcTable
WHERE MyKey IN (SELECT MyKey FROM destTable)

但是,我的表有多个键,我想不出你怎么能用多个键做到这一点。

知道我做错了什么,或者你有更好的想法吗?

9 个答案:

答案 0 :(得分:46)

您的问题是您需要子查询中的另一个where子句来标识复制的内容:

INSERT INTO destTable
SELECT Field1,Field2,Field3,... 
FROM srcTable
WHERE NOT EXISTS(SELECT * 
                 FROM destTable 
                 WHERE (srcTable.Field1=destTable.Field1 and
                       SrcTable.Field2=DestTable.Field2...etc.)
                 )

正如另一位回答者所指出的,外部联接可能是一种更简洁的方法。我上面的例子只是尝试解释使用您当前的查询更容易理解。这两种方法都可以在技术上起作用。

INSERT INTO destTable
SELECT s.field1,s.field2,s.field3,... 
FROM srcTable s 
       LEFT JOIN destTable d ON (d.Key1 = s.Key1 AND d.Key2 = s.Key2 AND...)
WHERE d.Key1 IS NULL

上述两种方法都假设您担心从源中插入可能已在目标中的行。如果你担心源有重复行的可能性,你应该尝试类似的东西。

INSERT INTO destTable
SELECT Distinct field1,field2,field3,... 
FROM srcTable  

还有一件事。我还建议在insert语句中列出特定字段,而不是使用SELECT *。

答案 1 :(得分:17)

我意识到这已经过时了,但是我从谷歌来到这里,在查看了接受的答案后,我做了我自己的陈述,这对我有用,希望有人会发现它有用:

    INSERT IGNORE INTO destTable SELECT id, field2,field3... FROM origTable

编辑:这适用于MySQL我没有在MSSQL上测试

答案 2 :(得分:4)

这样的东西?:

INSERT INTO destTable
SELECT s.* FROM srcTable s
LEFT JOIN destTable d ON d.Key1 = s.Key1 AND d.Key2 = s.Key2 AND...
WHERE d.Key1 IS NULL

答案 3 :(得分:4)

我希望此查询可以帮助您

INSERT INTO `dTable` (`field1`, `field2`)
SELECT field1, field2 FROM `sTable` 
WHERE `sTable`.`field1` NOT IN (SELECT `field1` FROM `dTable`)

答案 4 :(得分:2)

您是否尝试过SELECT DISTINCT?

INSERT INTO destTable
SELECT DISTINCT * FROM srcTable

答案 5 :(得分:1)

insert into tbl2
select field1,field2,... from tbl1
where not exists 
    ( 
        select field1,field2,... 
        from person2
        where (tbl1.field1=tbl2.field1 and
        tbl1.field2=tbl2.field2 and .....)
    )

答案 6 :(得分:0)

DISTINCT是您正在寻找的关键字。

在MSSQL中,将表中的唯一行复制到另一个表可以这样做:

SELECT DISTINCT column_name
INTO newTable
FROM srcTable

column_name是您要搜索的唯一值的列。

经过测试和工作。

答案 7 :(得分:0)

使用PHP / PDO为我工作的解决方案。

public function createTrainingDatabase($p_iRecordnr){
// Methode: Create an database envirioment for a student by copying the original
// @parameter: $p_iRecordNumber,    type:integer,   scope:local
// @var: $this->sPdoQuery,          type:string,    scope:member 
// @var: $bSuccess,                 type:boolean,   scope:local
// @var: $aTables,                  type:array,     scope:local
// @var: $iUsernumber,              type:integer,   scope:local
// @var: $sNewDBName,               type:string,    scope:local
// @var: $iIndex,                   type:integer,   scope:local 

// -- Create first the name of the new database --
$aStudentcard = $this->fetchUsercardByRecordnr($p_iRecordnr);
$iUserNumber = $aStudentcard[0][3];
$sNewDBName = $_SESSION['DB_name']."_".$iUserNumber;
// -- Then create the new database  --
$this->sPdoQuery = "CREATE DATABASE `".$sNewDBName."`;";
$this->PdoSqlReturnTrue();
// -- Create an array with the tables you want to be copied --
$aTables = array('1eTablename','2ndTablename','3thTablename');
// -- Populate the database --
for ($iIndex = 0; $iIndex < count($aTables); $iIndex++) 
{
 // -- Create the table --
    $this->sPdoQuery = "CREATE TABLE `".$sNewDBName."`.`".$aTables[$iIndex]."` LIKE `".$_SESSION['DB_name']."`.`".$aTables[$iIndex]."`;";
    $bSuccess = $this->PdoSqlReturnTrue();
    if(!$bSuccess ){echo("Could not create table: ".$aTables[$iIndex]."<BR>");}
    else{echo("Created the table ".$aTables[$iIndex]."<BR>");}
    // -- Fill the table --
    $this->sPdoQuery = "REPLACE `".$sNewDBName."`.`".$aTables[$iIndex]."` SELECT * FROM `".$_SESSION['DB_name']."`.`".$aTables[$iIndex]."`";
    $bSuccess = $this->PdoSqlReturnTrue();
    if(!$bSuccess ){echo("Could not fill table: ".$aTables[$iIndex]."<BR>");}
    else{echo("Filled table ".$aTables[$index]."<BR>");}
}

}

答案 8 :(得分:0)

您是否尝试过先删除子查询中的重复项?

INSERT INTO destTable
SELECT source.* FROM(
    SELECT *
    FROM srcTable
    EXCEPT
    SELECT src.* FROM
    srcTable AS src
    INNER JOIN destTable AS dest 
    /* put in below line the conditions to match repeated registers */
        ON dest.SOME_FANCY_MATCH = src.SOME_FANCY_MATCH AND ... 
) as source

如果集合很大,也许这不是最佳解决方案。