PostgreSQL:子查询返回多个行

时间:2018-09-20 17:00:55

标签: postgresql

有人可以帮助我吗? 我已经检查过几次我的SQL代码,并且不明白为什么有时会发生错误。在每个子查询中,对LIMIT 1都有硬性限制,这样的子查询如何返回多行呢?

可以通过在两个并行连接中运行此查询来重现此问题。

numerical_pool_id列是主键,其值是唯一的(我已对其进行了两次检查)。

            WITH update_current(number) AS (
                UPDATE numeric_pool
                SET updating_field = updating_field + 1,
                    date_modified = NOW()
                WHERE numeric_pool_id = (
                    SELECT numeric_pool_id
                    FROM numeric_pool
                    WHERE condition_field1 = 58
                    AND condition_field2 = 4
                    AND date_modified < NOW() - INTERVAL '150 s'
                    AND updating_field < 1
                    ORDER BY numeric_pool_id
                    LIMIT 1
                )
                RETURNING number
            ), insert_new(number) AS (
                WITH pool(number) AS (
                    VALUES (100), (200)
                )
                INSERT INTO numeric_pool (number, condition_field1, condition_field2, updating_field, date_modified)
                SELECT * FROM (
                    SELECT p.number, 58, 4, 1, NOW()
                    FROM pool p
                    LEFT JOIN numeric_pool dp ON (
                        p.number = dp.number
                        AND dp.condition_field1 = 58
                        AND dp.condition_field2 = 4
                    )
                    WHERE dp.numeric_pool_id IS NULL
                    LIMIT 1
                ) subquery
                WHERE NOT EXISTS(SELECT * FROM update_current)
                RETURNING number
            ), update_old(number) AS (
                UPDATE numeric_pool
                SET updating_field = 1,
                    date_modified = NOW()
                WHERE NOT EXISTS(SELECT * FROM update_current)
                AND NOT EXISTS(SELECT * FROM insert_new)
                AND numeric_pool_id = (
                    SELECT numeric_pool_id
                    FROM numeric_pool
                    WHERE condition_field1 = 58
                    AND condition_field2 = 4
                    AND date_modified < NOW() - INTERVAL '0 s'
                    ORDER BY date_modified
                    LIMIT 1
                )
                RETURNING number
            )
            SELECT COALESCE(
                (SELECT * FROM update_current),
                (SELECT * FROM insert_new),
                (SELECT * FROM update_old)
            ) AS number

我通过拒绝使用COALESCE替换了查询的最后一部分,然后错误从数据库日志中消失了。因此,COALESCE的一个子查询返回了多行,可能是最后一个子查询,因为前两个子查询不应返回我的数据值。但是,此子查询是主键上的UPDATE,它不能返回多个行吗?

                SELECT number FROM (
                    SELECT * FROM update_current
                    UNION SELECT * FROM insert_new
                    UNION SELECT * FROM update_old
                ) finquery
                LIMIT 1

这是我的桌子:

CREATE TABLE numeric_pool
(
  numeric_pool_id serial NOT NULL, -- Primary key
  condition_field1 integer NOT NULL,
  "number" bigint NOT NULL,
  condition_field2 integer NOT NULL,
  updating_field integer NOT NULL,
  date_modified timestamp without time zone NOT NULL,
  CONSTRAINT numeric_pool_pkey PRIMARY KEY (numeric_pool_id)
)
WITH (
  OIDS=FALSE
);

此查询在我的应用程序中并行运行。

PostgreSQL 9.6.0 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit

0 个答案:

没有答案