【问题标题】:PostgreSQL Error more than one row returned by a subquery used as an expression用作表达式的子查询返回的 PostgreSQL 错误不止一行
【发布时间】:2021-07-07 14:23:21
【问题描述】:

我在查询单个列时遇到问题,如下所示:

SELECT a.ad_morg_key, count(a.sid_mpenduduk_key) AS total_population 
FROM sid_mpenduduk a 
GROUP BY a.ad_morg_key;

它确实有效。但是当我使用这样的查询查询多个列时:

SELECT a.ad_morg_key, b."name", 
count(b.sid_magama_key) AS total, 
count(b.sid_magama_key)::float / (SELECT count(a.sid_mpenduduk_key) 
FROM sid_mpenduduk a 
GROUP BY a.ad_morg_key)::float * 100::float AS percentage,
(SELECT count(a.sid_mpenduduk_key) FROM sid_mpenduduk a GROUP BY a.ad_morg_key) AS total_population
FROM sid_mpenduduk a
INNER JOIN sid_magama b ON a.sid_magama_key = b.sid_magama_key
GROUP BY a.ad_morg_key, b."name";

但它失败了:

ERROR:  more than one row returned by a subquery used as an expression

我想要这样的最终结果:

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    您的子查询按a.ad_morg_key 分组,因此它会为a.ad_morg_key 的每个不同值提供一行。

    一般来说,SELECT 语句中的每个子查询都应该返回一个值。假设您有一个名为A 的表。

    A_key A_value
    A1 200
    A2 200

    如果你执行

    SELECT (SELECT A_KEY FROM A) as keys
    FROM A
    

    子查询(SELECT A_KEY FROM A) 返回

    A_key
    A1
    A2

    那么keys 的值应该是多少? SQL 无法处理此决定,因此您应该选择其中一个值或将它们聚合为单个值。

    【讨论】:

    • 正确的 Horario,所以 SELECT (SELECT ARRAY_AGG(A_KEY) FROM A) as keys FROM A 将完成这项工作,或者您可以放置​​另一个聚合函数(如 count(...))而不是 ARRAY_AGG ,这样您就可以一切正常了!你可以添加这个答案,这将是一个地狱般的答案!
    【解决方案2】:

    改用关联子句:

    (SELECT count(a.sid_mpenduduk_key) 
     FROM sid_mpenduduk a2 
     WHERE a2.ad_morg_key = a.ad_morg_key
    ) AS total_population
    

    我不确定子查询是否真的有必要。因此,您可以考虑提出一个新的问题,其中包含示例数据、期望的结果以及对您想要做什么的清晰解释。

    【讨论】:

    • 也许你有另一种方法来计算基于 ad_morg_key 的人口分组?我只想根据 ad_morg_key 计算人口组
    • @Mr.Robot 。 . .正如答案所暗示的:提出一个问题,并提供适当的样本数据、期望的结果和解释。这些问题已经得到了不止一次的回答。
    【解决方案3】:

    你被烧死了

    GROUP BY ...
    (SELECT count(a.sid_mpenduduk_key) 
     FROM sid_mpenduduk a 
     GROUP BY a.ad_morg_key) AS total_population
    

    因为外部GROUP BY 需要一个标量,但子查询为每个a.ad_morg_key 生成一个计数。

    我不会那样写我的查询。而是生成一个虚拟表,

    SELECT a.ad_morg_key, b."name", 
    ...
    JOIN 
    (SELECT ad_morg_key, 
            count(sid_mpenduduk_key) as N
     FROM sid_mpenduduk
     GROUP BY ad_morg_key) AS morgs
    on ad_morg_key = morgs.ad_morg_key
    

    这样一来,每一行的计数为N,你可以随意划分,

    count(b.sid_magama_key)::float / morgs.N
    

    而且,如果你被绊倒了,你会得到比你预期更多的行而不是错误消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-09
      • 1970-01-01
      相关资源
      最近更新 更多