【问题标题】:UPDATE A table with subqueries with group by clause更新带有子查询的表和 group by 子句
【发布时间】:2021-09-19 19:32:56
【问题描述】:

我有两个结构如下的表

create table PARENT(
  pk varchar(255) not null, 
  ip_count int, 
  primary key(pk)
);

create table CHILD_INPUT(
  pk varchar(255) not null, 
  pk_parent varchar(255), 
  error varchar(255), 
  primary key(pk)
);

CHILD_INPUT 表具有引用“PARENT”表的“pk”列的外键“pk_parent”。

以下是一些示例数据:

父表:

PK IP_COUNT
PK0001 NULL
PK0002 NULL

CHILD_INPUT

PK PK_PARENT ERROR
CPK001 PK0001 ERR1
CPK002 PK0001 NULL
CPK003 PK0001 NULL
CPK004 PK0001 NULL
CPK005 PK0001 NULL
CPK006 PK0002 ERR
CPK007 PK0002 ERR
CPK008 PK0002 ERR

我需要编写一个更新查询,如果“ERROR”列为 NULL,我必须使用子记录的计数来更新 PARENT 表的“ip_count”,即预期输出应如下所示:

PK IP_COUNT
PK0001 4
PK0002 0

解释:PK0001 在子表中有 4 条记录,错误列设置为 NULL。 PK0002 子表中没有记录,错误设置为 NULL。

【问题讨论】:

    标签: sql oracle group-by subquery


    【解决方案1】:

    如果是 Oracle,那么 merge 可能会有所帮助。

    SQL> MERGE INTO parent p
      2       USING (  SELECT c.pk_parent,
      3                       SUM (CASE WHEN error IS NULL THEN 1 ELSE 0 END) cnt
      4                  FROM child_input c
      5              GROUP BY c.pk_parent) x
      6          ON (p.pk = x.pk_parent)
      7  WHEN MATCHED
      8  THEN
      9     UPDATE SET p.ip_count = x.cnt;
    
    2 rows merged.
    
    SQL> SELECT * FROM parent;
    
    PK           IP_COUNT
    ---------- ----------
    PK0001              4
    PK0002              0
    
    SQL>
    

    [编辑]如果某些父母没有孩子记录,那么UPDATE而不是MERGE

    SQL> select * from parent order by pk;
    
    PK           IP_COUNT
    ---------- ----------
    PK0001
    PK0002
    PK0003                     --> no child records for this parent
    
    SQL> select * from child_input order by pk_parent;
    
    PK         PK_PARENT  ERROR
    ---------- ---------- ----------
    CPK001     PK0001     ERR1
    CPK002     PK0001
    CPK003     PK0001
    CPK004     PK0001
    CPK005     PK0001
    CPK006     PK0002     ERR
    CPK007     PK0002     ERR
    CPK008     PK0002     ERR
    
    8 rows selected.
    

    更新:

    SQL> UPDATE parent p
      2     SET p.ip_count =
      3            (SELECT NVL (SUM (CASE WHEN error IS NULL THEN 1 ELSE 0 END), 0) cnt
      4               FROM child_input c
      5              WHERE c.pk_parent = p.pk);
    
    3 rows updated.
    

    结果:

    SQL> select * from parent order by pk;
    
    PK           IP_COUNT
    ---------- ----------
    PK0001              4
    PK0002              0
    PK0003              0
    
    SQL>
    

    【讨论】:

    • 抱歉回来晚了。但是我这里还有一个条件,如果也没有子行,我需要为计数显示 0
    • 更新,然后。我编辑了答案并添加了一个示例。
    【解决方案2】:

    假设这是 MySQL...

    DROP TABLE IF EXISTS my_table;
    
    CREATE TABLE my_table
    (PK SERIAL PRIMARY KEY
    ,PK_PARENT INT NOT NULL
    ,ERROR VARCHAR(12) NULL
    );
    
    INSERT INTO my_table VALUES
    (1,1,'ERR1'),
    (2,1,NULL),
    (3,1,NULL),
    (4,1,NULL),
    (5,1,NULL),
    (6,2,'ERR'),
    (7,2,'ERR'),
    (8,2,'ERR');
    
    SELECT pk_parent,SUM(error is null) ip_count FROM my_table GROUP BY pk_parent;
    +-----------+----------+
    | pk_parent | ip_count |
    +-----------+----------+
    |         1 |        4 |
    |         2 |        0 |
    +-----------+----------+
    

    【讨论】:

    • 我需要在mysql和oracle中都做。在 mysql 中它正在工作,但对于 oracle 我收到一个错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多