UPDATE A table with subqueries with group by 子句

UPDATE A table with subqueries with group by clause

我有两个table结构如下

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 table 有外键“pk_parent”,它引用了“PARENT”table.

的“pk”列

下面是一些示例数据:

PARENT TABLE:

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

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

PK IP_COUNT
PK0001 4
PK0002 0

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

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

如果是 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>

[编辑] 如果某些 parents 没有 child 记录,则 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>