【问题标题】:delete rows in postgresql删除postgresql中的行
【发布时间】:2016-06-12 04:40:09
【问题描述】:

我有一个log 表如下:

id  status1 status2  ref  dateofchange
1     10      12      33     1.1.10
2     10      12      34     1.1.15
3     5        8      14     1.5.10
4     10      12      33     2.1.10

还有一张表tab如下:

id ref qty  commitdate
1   17  5    1.1.10
2   33  8    1.1.10
3   34  7    1.12.14
4   34  8    1.2.16
5   34  8    1.1.15

我有一个查询,它给了我来自log 表的行:

select *
from log
where status1=10 and status2=12

这给出了:

id  status1 status2  ref  dateofchange
1     10      12      33     1.1.10
2     10      12      34     1.1.15
4     10      12      33     2.1.10

对于这些行中的每一行,我想从标签中删除 log.ref=tab.ref and tab.commitdate<=log.dateofchange 的所有行

删除标签表后应如下所示:

id ref qty  commitdate
1   17  5    1.1.10
4   34  8    1.2.16

我尝试使用 WITH 查询来做到这一点:

With l as (
    select *
    from log
    where status1=10 and status2=12
)
delete from tab where l.ref=tab.ref and tab.commitdate<=l.dateofchange

但是这不起作用。

错误:表“l”缺少 FROM 子句条目

我该怎么做?

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    DELETE 语句中加入表的语法与updateselect 语句中的语法不同。您需要使用USING 才能在delete 语句中加入表

    with l as (
        select *
        from log
        where status1=10 and status2=12
    )
    delete from tab 
    using l
    where l.ref=tab.ref 
      and tab.commitdate <= l.dateofchange;
    

    或没有 CTE:

    delete from tab 
    using log l
    where l.ref = tab.ref 
      and l.status1 = 10
      and l.status2 = 12
      and tab.commitdate <= l.dateofchange;
    

    这也可以在没有连接的情况下编写,使用共同相关的子查询:

    delete from tab
    where exists (select *
                  from log as l
                  where l.status1 = 10 
                    and l.status2 = 12
                    and tab.commitdate <= l.dateofchange);
    

    【讨论】:

    • 我不明白 co-related 子查询。我不想从选项卡中删除所有内容...我只想删除 ref 相同且日期早于日志表中写入的行。
    • @java:这就是where 子句中的exists 运算符的用途。该语句不会删除 tab 中的所有行 - 仅删除那些存在子查询中的行的行(因此得名)。
    • 但是它如何检查日期呢?日期不一定匹配。
    • @java: 检查是 in 子查询:and tab.commitdate &lt;= l.dateofchange
    【解决方案2】:

    为了JOIN,您需要一个USING 子句:

    WITH l AS (
        SELECT *
        FROM log
        WHERE status1=10 AND status2=12
    )
    DELETE FROM tab 
    USING l
    WHERE l.ref=tab.ref AND tab.commitdate <= l.dateofchange;
    

    【讨论】:

      猜你喜欢
      • 2016-03-07
      • 2020-10-21
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 2010-09-07
      • 2016-02-15
      相关资源
      最近更新 更多