【问题标题】:SQL - find records from one table which exist in another and delete if notSQL - 从一个表中查找存在于另一个表中的记录,如果不存在则删除
【发布时间】:2020-05-11 04:42:21
【问题描述】:

我有以下四个 SQL 表:

Table 1:
-----------------------
Product | Date_Purchase
-----------------------
abc     | 06-Jan-19
def     | 05-Jan-18
ghi     | 05-Apr-19
abc     | 06-Feb-19

Table 2:

------------------------
Product | Date_Purchase
------------------------
jkl    | 6-Feb-19
mno    | 2-Aug-18
ghi    | 9-May-19
pqr    | 1-Sep-19

Table 3:

-------------------------
Product | Date_Purchase
-------------------------
ghi    | 2-Aug-18
mno    | 9-May-19
pqr    | 2-Aug-18
abc    | 06-Jan-19

Table 4:

-------------------------
Product | Date_Purchase
-------------------------
stu    | 9-May-19
vwx    | 05-Apr-19
ghi    | 9-May-19
def    | 05-Jan-18

我有以下代码将表格与 Union 连接起来:

SELECT Product, Date_Purchase FROM Table1 UNION ALL
SELECT Product, Date_Purchase FROM Table2 UNION ALL
SELECT Product, Date_Purchase FROM Table3 UNION ALL SELECT Product, Date_Purchase FROM Table4
ORDER BY Product, Date_Purchase;

我想从表格中删除所有在所有表格中只出现一次的行,无论是哪个表格。

例如 jkl、stu 和 vwx 只出现一次,所以我想从它们出现的表中删除整行。有谁知道该怎么做? 另外,如何删除表格中出现且购买日期相同的所有产品?

【问题讨论】:

  • 这能回答你的问题吗? How to Delete Records NOT IN
  • 您使用的是什么 DBMS(Oracle、MySQL 等)?我怀疑您是否能够在一次操作中从所有四个表中删除。您可能需要将所有要删除的项目填充到临时表中,然后执行四次删除(每个源表一次)以删除在临时表中找到的所有项目。
  • 您的问题解决了吗?那么请告诉我们。
  • forpas 提供的解决方案奏效了!谢谢大家

标签: sql union-all


【解决方案1】:

试一试 Scratte 的版本,仅当产品和日期出现两次时(未选中,因为写在移动设备上):

SELECT pdo.*
FROM (SELECT pd.*, COUNT(*) OVER (PARTITION BY Product) as cnt
      FROM ((SELECT Product, Date_Purchase FROM Table1
            ) UNION ALL
            (SELECT Product, Date_Purchase FROM Table2
            ) UNION ALL
            (SELECT Product, Date_Purchase FROM Table3
            ) UNION ALL
            (SELECT Product, Date_Purchase FROM Table4
            )
           ) pd
     ) pdo
Group by pdo.Product,pdo.Date_Purchase
Having cnt=1

【讨论】:

    【解决方案2】:

    MySql 的解决方案,您可以在 1 条语句中从所有 4 个表中删除:

    delete t1, t2, t3, t4
    from (
      select u.product, count(*) counter 
      from (
        select * from table1 union all
        select * from table2 union all
        select * from table3 union all
        select * from table4
      ) u  
      group by u.product
    ) t 
    left join table1 t1 on t1.product = t.product
    left join table2 t2 on t2.product = t.product
    left join table3 t3 on t3.product = t.product
    left join table4 t4 on t4.product = t.product
    where t.counter = 1; 
    

    请参阅demo。
    结果:

    表1

    > Product | Date_Purchase
    > :------ | :------------
    > abc     | 06-Jan-19    
    > def     | 05-Jan-18    
    > ghi     | 05-Apr-19    
    > abc     | 06-Feb-19  
    

    表2

    > Product | Date_Purchase
    > :------ | :------------
    > mno     | 2-Aug-18     
    > ghi     | 9-May-19     
    > pqr     | 1-Sep-19 
    

    表3

    > Product | Date_Purchase
    > :------ | :------------
    > ghi     | 2-Aug-18     
    > mno     | 9-May-19     
    > pqr     | 2-Aug-18     
    > abc     | 06-Jan-19 
    

    表4

    > Product | Date_Purchase
    > :------ | :------------
    > ghi     | 9-May-19     
    > def     | 05-Jan-18 
    

    【讨论】:

      【解决方案3】:

      如果“删除”意味着不返回,则将它们返回到select,那么:

      SELECT pd.*
      FROM (SELECT pd.*, COUNT(*) OVER (PARTITION BY Product) as cnt
            FROM ((SELECT Product, Date_Purchase FROM Table1
                  ) UNION ALL
                  (SELECT Product, Date_Purchase FROM Table2
                  ) UNION ALL
                  (SELECT Product, Date_Purchase FROM Table3
                  ) UNION ALL
                  (SELECT Product, Date_Purchase FROM Table4
                  )
                 ) pd
           ) pd
      WHERE cnt = 1;
      

      如果“删除”的意思是delete,那么您需要四个delete 语句,每个语句如下:

      delete t
         from table1 t
         where not exists (select 1 from table2 where t2.product = t.product) and
               not exists (select 1 from table3 where t3.product = t.product) and
               not exists (select 1 from table4 where t4.product = t.product);
      

      实际上,这会删除仅在桌子上的产品,即使它们多次出现。如果也有必要,可以对其进行调整以仅删除单例。

      【讨论】:

      • 如果“在所有表格中只出现一次”包含购买日期怎么办?
      • @Scratte 第一版还是第二版?
      • @Nikolaus 两者。 abc 来自 abc | 06-Feb-19 (table1) 不会出现在第一个。
      • @Scratte 。 . .那将是一个不同的问题。如果您有兴趣,可以将那个问题作为一个新问题提出。
      猜你喜欢
      • 2010-09-26
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      相关资源
      最近更新 更多