【问题标题】:Compare two tables and select the record that is no in table 2比较两个表,选择表2中没有的记录
【发布时间】:2015-10-29 13:22:08
【问题描述】:

我想编写一个选择查询来比较这两个表。通过比较它应该知道需要从表 2 中更新、插入或删除哪些记录。

表格内容:

Table 1
----- ---------
 id    name
----- ---------
 1     shubham
 2     ravi
 3     aman
 4     vijay


Table 2
----- ---------
 id    name
----- ---------
 1     shubham
 2     ravi
 3     aman
 4     vijay

现在,当table1 中的数据发生更改时,两个表都具有相同的数据

Table 1
----- ---------
 id    name
----- ---------
 1     shubham
 2     harish
 3     aman                        
 5     saurabh

现在在 table1 中,id 2 的名称被更新,id 4 被删除,id 也被插入。我希望我的查询从表 1 中选择所有这些记录,还告诉是否要执行哪个操作。我也不想使用集合运算符。请帮忙

【问题讨论】:

  • 呃,select * from table1 MINUS select * from table2?
  • 您是否还看到标题全部大写且布局非常奇怪?
  • 您正在使用 RDBMS 但不想使用集合运算符?您可能需要重新考虑您的工具或方法。
  • 您可能还希望浏览一下help page,了解此站点上的富文本编辑器小部件。
  • 我还想显示要更新、删除或插入的记录,而不仅仅是显示它们。

标签: sql oracle


【解决方案1】:

此解决方案中不涉及集合运算符,但当要比较的列不止几列时,它们可能更易于使用:

select coalesce(s.id, d.id) id
     , coalesce(s.name, d.name) name
     , case when s.id is null then 'D'
            when d.id is null then 'C'
            when s.name != d.name then 'U'
       end CUD
  from table1 s
  full join table2 d
    on s.id = d.id
 where s.id is null
    or d.id is null
    or s.name != d.name

CUD 列仅表示执行Create、Update 或Delete 的操作。更灵活的基于集合的解决方案是这样的:

select 'CU' op, s.* from table1 s
minus
select 'CU' op, d.* from table2 d
union
select 'D' op, d.* from table2 d where d.id not in (select s.id from table1 s)

在这种情况下,您不知道减号操作后留下的 table1 记录是新的还是更改的,因此操作是 Create 或 Update,但您仍然明确知道 Delete 操作.

这些查询中的任何一个都可以在MERGE 语句的USING 子句中使用,以更新table2 以匹配table1

【讨论】:

    【解决方案2】:

    我会这样做:

    select coalesce(t1.id, t2.id) id, t1.name new_name, t2.name old_name,
        case when t1.id is null then 'row deleted'
             when t2.id is null then 'row inserted'
             when t1.name <> t2.name  
               or t1.name is null and t2.name is not null
               or t1.name is not null and t2.name is null
             then 'data changed'
        end change
      from t1 full join t2 on t1.id = t2.id order by id
    

    SQLFiddle

    顺便说一句,在你的问题中格式化数据有什么难的?只需在某事前添加 4 个空格,这将显示为代码。或者选择某个部分并按 [Ctrl-K]。一切都在您编写时呈现。

    【讨论】:

    • @AdityaShrivastava - 我想知道 stackexchange 对这个问题的回答,你链接了,看来你在那里得到了很好的答案。但是你没有说WHY你想改变正确的方式(你发布的这个,sum() ... over())到别的东西吗?您是否试图尽可能地保持严格的 SQL?请告诉我,我很好奇 ;-)
    • 我尝试使用 ANSI 标准。它也帮助我学习新方法。感谢您的帮助...您总是有我想要的答案
    【解决方案3】:
    SELECT 
    TEST1.NAME,TEST1.CLASS,test2.name,test2.class,
    case  when test1.name 
    is null then 'deleted'  
    when UPPER(test1.name)!=UPPER(test2.name) then 'insert'
    when test2.name is null then 'updated' ELSE 'no change' end as flag
    FROM    TEST1
    full outer join TEST2
      ON  
     test2.class=test1.class;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 2015-08-18
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多