【问题标题】:Multiple joins and aggregate functions producing incorrect totals多个连接和聚合函数产生不正确的总数
【发布时间】:2020-06-10 15:04:00
【问题描述】:

我有 4 张桌子。

LAYERS 

id(pk)        location
-----------------------
  1            Bristol
  2            London

FEATURES

fid(pk)      layer_id(fk)     category
-----------------------------------------
  1.001        1                  Rank1
  1.002        1                  Rank2
  1.003        1                  Rank1
  2.001        2                  Rank3
  2.002        2                  Rank1

TOWN_STATUS 

id(pk)     town_id(fk)      fid(fk)      status
--------------------------------------------------
  1            5             1.001       AT_RISK
  2            6             1.001       DANGER
  3            19            2.002       DANGER
  4            23            2.002       DANGER
  5            24            2.002       AT_RISK
  6            30            2.002       DANGER

LANDMARK_STATUS 

id(pk)     landmark_id(fk)      fid(fk)      status
--------------------------------------------------
  1            1             1.002       DANGER
  2            10            1.002       DANGER
  3            11            2.002       DANGER
  4            13            2.002       AT_RISK

FEATURES 表中的每条记录都链接到LAYERS 表中的一条记录。

空间触发器对要素表进行操作,以将记录插入到 TOWN_STATUSLANDMARK_STATUS 表中。

TOWN_STATUSLANDMARK_STATUS 表中的状态列只能具有 2 个值之一,例如'AT RISK''DANGER'

我想创建一个表格来计算一个类别中的特征数量以及有多少'AT RISK''DANGER'statuses 该类别导致并由特定层过滤。例如,表格如下所示:

    category   feature_num    at_risk_num   danger_num
--------------------------------------------------------
    Rank1         3                 1         5
    Rank2         1                 0         3
    Rank3         1                 0         0 

目前我有一个看起来像这样的 (Postgre)SQL 查询

SELECT feature.category,
    count(feature.category) AS count,
    sum(
        CASE
            WHEN town_status.status = 'AT_RISK' OR landmark_status.status 'AT_RISK' THEN 1
            ELSE NULL
        END) AS at_risk_num,
    sum(
        CASE
            WHEN town_status.status::text = 'DANGER' OR landmark_status.status = 'DANGER' THEN 1
            ELSE NULL
        END) AS danger_num
   FROM features
     LEFT JOIN layer ON layer.id = feature.layer_id
     LEFT JOIN town_status ON town_status.fid = feature.fid
     LEFT JOIN landmark_status ON landmark_status.fid = feature.fid
  WHERE layer.location = 'Bristol'
  GROUP BY features.category
  ORDER BY features.category;

但是,当我这样做时,feature_num 列的总数不正确。由于this answer,我知道这与连接有关,但我不知道如何根据特征类别形成最后两列。

【问题讨论】:

  • 这似乎是一个常见的错误,人们想要一些连接,每个可能涉及不同的键,一些子查询,每个可能涉及连接和/或聚合,但他们错误地尝试执行所有然后加入所有聚合或聚合以前的聚合。 PS当你得到一个你不期望/不理解的结果时,停止试图找到你的总体目标并找出你的误解是。--隔离第一个错误的子表达式及其输入和输出,了解什么是误解、错字、错误的推理,等导致它。 (调试基础。)问这个。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。对于包含最少代码的错误,您可以给出的代码是您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)How to Ask 适用于包含 DBMS 和 DDL 的 SQL,其中包括约束、索引和表格初始化。

标签: sql postgresql join left-join aggregate-functions


【解决方案1】:

聚合之前加入:

SELECT f.category,
       COALESCE(ts.cnt, 0) + (COALESCE(ls.cnt, 0) as count,
       COALESCE(ts.at_risk, 0) + (COALESCE(ls.at_risk, 0) as at_risk,
       COALESCE(ts.danger, 0) + (COALESCE(ls.danger, 0) as danger
FROM features f LEFT JOIN
     layer l
     ON l.id = f.layer_id LEFT JOIN
     (SELECT ts.fid, COUNT(*) as cnt,
             COUNT(*) FILTER (WHERE ts.status = 'AT_RISK') as at_risk,
             COUNT(*) FILTER (WHERE ts.status = 'DANGER') as danger
      FROM town_status ts
      GROUP BY ts.fid
     ) ts
     ON town_status.fid = f.fid
     (SELECT ls.fid, COUNT(*) as cnt,
             COUNT(*) FILTER (WHERE ls.status = 'AT_RISK') as at_risk,
             COUNT(*) FILTER (WHERE ls.status = 'DANGER') as danger
      FROM landmark_status ls
      GROUP BY ls.fid
     ) ls
     ON ls.fid = f.fid;
WHERE l.location = 'Bristol'
GROUP BY f.category
ORDER BY f.category;

【讨论】:

  • 谢谢!我必须为我的 Postgres 版本稍微修改它,但我想我已经有了这个概念:)
猜你喜欢
  • 2013-02-22
  • 2015-11-22
  • 2022-11-25
  • 1970-01-01
  • 2014-04-25
  • 2014-09-07
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多