我有两张桌子,例如:
Table A Table B
======= =======
Name | Color Name | Color
---------------------- ----------------------
Mickey Mouse | red Mickey Mouse | red
Donald Duck | green Donald Duck | blue
Donald Duck | blue Minnie | red
Goofy | black
Minnie | red
表A是我的源表,B是目标表。现在我需要一个查询来查找表A中的所有不同(附加)行,因此可以使用这些行更新表B. 所以我需要一个查询,它从表A中找到以下行:
Name | Color
----------------------
Donald Duck | green
Goofy | black
这种查询的好方法是什么?它应尽可能高效(避免过多的连接)。 谢谢你的帮助!
答案 0 :(得分:9)
我会使用NOT EXISTS结构。
SELECT Name, Color
FROM TableA
WHERE NOT EXISTS (
SELECT 1 FROM TableB
WHERE TableA.Name = TableB.Name
AND TableA.Color = TableB.Color)
答案 1 :(得分:7)
SELECT a.Name, a.Color
FROM a LEFT OUTER JOIN b ON (a.Name = b.Name AND a.Color = b.Color)
WHERE b.Name IS NULL AND b.Color IS NULL
答案 2 :(得分:4)
Select A.Name, A.Color
From A left join B on A.Name = B.Name and A.Color = B.Color
Where B.Name is null
答案 3 :(得分:2)
在SQL Server 2008中,您可以使用EXCEPT
运算符,该运算符像UNION
一样使用但返回第一个查询中的所有内容,除非它也位于第二个查询中:
SELECT * FROM TABLEA EXCEPT SELECT * FROM TABLEB
我知道Oracle有一个MINUS
运算符可以执行相同的操作。
答案 4 :(得分:2)
您可以使用EXCEPT运算符,它与UNION相反。在Oracle中,相当于MINUS。
SELECT * FROM TABLE_A
EXCEPT
SELECT * FROM TABLE_B
答案 5 :(得分:2)
我通常添加一列“更新TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP”,并使用其值来检查插入新行或修改现有行的时间。
在我开发的应用程序中,我需要解决类似于你的问题,所以我保存了B的MAX(更新)的某个地方,然后通过查询确定了A.updated> B.updated的所有行,并且结果是所有新的+修改过的行。
由于字段默认值为CURRENT_TIMESTAMP且自动更新“ON UPDATE”,因此您无需显式设置其值。
答案 6 :(得分:1)
NOT EXISTS
子查询应解析为外连接:
SELECT Name, Color
FROM TableA
WHERE NOT EXISTS (
SELECT 1
FROM TableB
WHERE TableA.Color = TableB.Color
AND TableA.Name = TableB.Name
)
或者您可以直接使用外部联接:
SELECT TableA.Name, TableA.Color
FROM TableA
LEFT OUTER JOIN TableB
ON TableA.Name = TableB.Name
AND TableA.Color = TableB.Color
WHERE TableB.Name IS NULL
他们应该具有同等的表现;这是一个你觉得更直观的问题。
答案 7 :(得分:1)
已经有很多正确的答案,但我想提出一个哲学观点:
此数据库架构在单个架构内的生产环境中是否真的可行?
让两个包含数据的表,然后编写一个查询来比较一个是否真的有意义吗?我认为只有一个表是有意义的,也许放入一个日期标识符来查找在某一点之后添加的记录。
我能想到的唯一情况就是你有两个独立的数据库,你想要“同步”它们,或者当你想要找到两者之间的差异时,比如说备份和生产。
答案 8 :(得分:1)
在Oracle中你可能会使用:
MERGE INTO b USING
(SELECT name, color
FROM a) src
ON (src.name = b.name AND color = src.color)
WHEN NOT MATCHED THEN
INSERT (name, color)
VALUES (src.name, src.color);
如果你的表有一个主键(你真的有没有一个表吗?),比如NAME,你想根据表B中记录的存在进行INSERT或UPDATE,你可以使用:
MERGE INTO b USING
(SELECT name, color
FROM a) src
ON (src.name = b.name)
WHEN NOT MATCHED THEN
INSERT (name, color)
VALUES (src.name, src.color)
WHEN MATCHED THEN
UPDATE
SET color = src.color;
我认为SQL Server也有MERGE语句或类似语句。
答案 9 :(得分:0)
SELECT TableA.Name, TableA.Color
FROM TableA
WHERE TableA.Name + TableA.Color NOT IN (SELECT TableB.Name + TableB.Color FROM TableB)
答案 10 :(得分:0)
INSERT INTO B
SELECT a.Name, a.Color
FROM A a
LEFT JOIN B b ON a.Name = b.Name AND a.Color = b.Color
WHERE b.Color IS NULL AND b.Name IS NULL
答案 11 :(得分:0)
public static TableId getTemporaryTable(String query) throws InterruptedException{
QueryJobConfiguration queryConfig =
QueryJobConfiguration.newBuilder(query)
.setUseLegacySql(false)
.build();
Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).build());
queryJob = queryJob.waitFor(); // Wait for the query to complete.
return ((QueryJobConfiguration) queryJob.getConfiguration()).getDestinationTable();
}
可以在 db fiddle
找到工作腼腆