具有 count(*) 的更新子句

Update clause with having count(*)

我有一个显示协议和协议状态的查询,其中只有一个参与者并且协议已打开:

SELECT a.protocol_number, b.STATUS_NAME, COUNT(*) FROM PARTICIPANTS a LEFT JOIN PROTOCOLS b ON a.PROTOCOL_NUMBER = b.PROTOCOL_NUMBER GROUP BY a.PROTOCOL_NUMBER, b.STATUS_NAME HAVING count(*) = 1 AND b.STATUS_NAME = 'OPEN';

我想将这些协议的状态更新为已关闭,但我没有找到运行正常的查询。试过这个,但它永远挂起:

UPDATE
    PROTOCOLS p1
SET
    p1.STATUS_NAME = 'CLOSED'
WHERE
    p1.protocol_Number IN (
    SELECT
        PROTOCOL_NUMBER
    FROM
        (
        SELECT
            a.protocol_number, b.STATUS_NAME, COUNT(*)
        FROM
            PARTICIPANTS a
        LEFT JOIN PROTOCOLS b ON
            a.PROTOCOL_NUMBER = b.PROTOCOL_NUMBER
        GROUP BY
            a.PROTOCOL_NUMBER, b.STATUS_NAME
        HAVING
            count(*) = 1
            AND b.STATUS_NAME = 'OPEN');

假设 STATUS_NAME 'OPEN' 仅被分配一次给 PROTOCOL_NUMBER.

,这应该更快并且在语义上是等效的
UPDATE
    PROTOCOLS p1
SET
    p1.STATUS_NAME = 'CLOSED'
WHERE
    STATUS_NAME = 'OPEN'
    and not exists (select null
                from protocols p2
                where p2.PROTOCOL_NUMBER = p1.PROTOCOL_NUMBER
                 and b.STATUS_NAME <> 'OPEN');

对于您的更新查询,您不需要在子查询中再次加入协议 table 并且使用 exists 我们可以将其与外部查询相关联。

假设您有 protocol_number 的索引,下面应该可以完成工作。你可以试试下面的,

update protocols p1
   set p1.status_name = 'CLOSED'
 where p1.status_name = 'OPEN'
   and exists (select 1
                 from participants a
                where a.protocol_number = b.protocol_number
                group by a.protocol_number
                having count(*) = 1)