Несколько объединений и агрегатных функций, производящих неправильные итоги - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть 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_STATUS и LANDMARK_STATUS.

Столбцы состояния в таблицах TOWN_STATUS и LANDMARK_STATUS могут иметь только одно из 2 значений, например 'AT RISK' или 'DANGER'

Я хотел бы создать таблицу, которая будет подсчитывать количество объектов в категории, а также сколько 'AT RISK' или 'DANGER' статусов этой категории вызвано и отфильтровано конкретным слоем. Например, таблица будет выглядеть следующим образом:

    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. Я знаю, что это как-то связано с объединениями из-за этого ответа , но я не могу понять, как формировать последние два столбца на основе категории объектов.

1 Ответ

1 голос
/ 26 февраля 2020

Совокупность до присоединения:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...