UPDATE 带有子查询的表,带有 group by 子句

时间:2021-07-09 12:25:56

标签: sql oracle group-by subquery

我有两个具有以下结构的表

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 表有外键“pk_parent”,它引用了“PARENT”表的“pk”列。

以下是一些示例数据:

父表:

<头>
PK IP_COUNT
PK0001 NULL
PK0002 NULL

CHILD_INPUT

<头>
PK PK_PARENT 错误
CPK001 PK0001 错误1
CPK002 PK0001 NULL
CPK003 PK0001 NULL
CPK004 PK0001 NULL
CPK005 PK0001 NULL
CPK006 PK0002 错误
CPK007 PK0002 错误
CPK008 PK0002 错误

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

<头>
PK IP_COUNT
PK0001 4
PK0002 0

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

2 个答案:

答案 0 :(得分:1)

假设这是 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 |
+-----------+----------+

答案 1 :(得分: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>