我有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)
但是,我的表有多个键,我想不出你怎么能用多个键做到这一点。
知道我做错了什么,或者你有更好的想法吗?
答案 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
如果集合很大,也许这不是最佳解决方案。