繁体   English   中英

SQL - 检查表中是否有新行?

[英]SQL - Check table for new rows?

我有两个表,例如:

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

这种查询的好方法是什么? 它应该尽可能高效(避免太多连接)。 谢谢你的帮助!

我会使用 NOT EXISTS 结构。

SELECT Name, Color
FROM TableA
WHERE NOT EXISTS (
SELECT 1 FROM TableB
WHERE TableA.Name = TableB.Name 
AND TableA.Color = TableB.Color)
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
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

在 SQL Server 2008 中,您可以使用EXCEPT运算符,它的用法类似于UNION但返回第一个查询中的所有内容,除了它也在第二个查询中:

SELECT * FROM TABLEA EXCEPT SELECT * FROM TABLEB

我知道 Oracle 有一个MINUS运算符可以做同样的事情。

您可以使用 EXCEPT 运算符,它与 UNION 相反。 在 Oracle 中,相当于 MINUS。

SELECT * FROM TABLE_A
EXCEPT
SELECT * FROM TABLE_B

我通常添加一列“updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP”,我使用它的值来检查何时插入新行或修改现有行。

在我开发的一个应用程序中,我需要解决一个与您类似的问题,所以我将 B 的 MAX(updated) 保存在某处,然后通过查询识别出 A.updated>B.updated 的所有行,结果是所有新的+修改的行。

由于字段默认值为 CURRENT_TIMESTAMP 并且它会自动更新“ON UPDATE”,因此您无需明确设置其值。

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

它们的性能应该相同; 这是一个你觉得更直观的问题。

已经有很多正确的答案,但我想提出一个哲学观点:

这个数据库模式在单个模式内的生产环境中真的可行吗?

有两个包含数据的表,然后编写一个查询来比较一个和另一个真的有意义吗? 我认为只有一个表是有意义的,也许可以输入一个日期标识符来查找在某个点之后添加的记录。

我能想到的唯一情况是你有两个独立的数据库并且你想要“同步”它们,或者当你想要找到两者之间的差异时,比如比较备份和生产.

在 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 中记录的存在来插入或更新,你可以使用:

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 语句或类似的语句。

SELECT TableA.Name, TableA.Color FROM TableA WHERE TableA.Name + TableA.Color NOT IN (SELECT TableB.Name + TableB.Color FROM TableB)

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
    select 
        name, 
        color
    from 
        tableA 
    where 
        concat(name, '|',color)  
        not in 
        (
            select 
                concat(name, '|',color) 
            from 
                tableB
        )-- not in 

工作腼腆可以在db fiddle找到

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM