PostgreSQL:基于不同列中的不同条目计数

时间:2017-01-09 20:09:08

标签: sql postgresql

以下是txn表的架构 -

 ID |   SrcNO   |    DstNO    | SrcCountry | DstCountry |   Type   | 
  1       A            B            USA          UK         RECV
  2       A            B            USA          UK         RECV
  3       B            H            UK           IND        SEND  
  4       C            D            UK           GER        SEND  

目的是捕获从英国的SrcNO / DstNo到其他国家的txns计数。换句话说,我想分别对任何SrcNo / DstNo的英国为SrcCountry / DstCountry的txn的计数 -

 No |  Country  | Send | RECV 
  B      USA        0      2
  B      IND        1      0 
  B      GER        0      0  
  C      USA        0      0
  C      IND        0      0 
  C      GER        1      0

备注 - 由于没有任何txn发送/ recv用于B与GER和C与USA,IND我们必须在两个案例SEND / RECV中显示计数为0.

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

怎么样:

select country, No, sum(send) as send, sum(recv) as recv
from ((select srcCountry as country, dstNo as No, 1 as send, 0 as recv
       from t
       where dstCountry = 'UK' and type = 'SEND'
      ) union all
      (select srcCountry as country, dstNo as No, 0 as send, 1 as recv
       from t
       where dstCountry = 'UK' and type = 'RECV'
      ) union all
      (select destCountry as country, dstNo as No, 1 as send, 0 as recv
       from t
       where srcCountry = 'UK' and type = 'SEND'
      ) union all
      (select dstCountry as country, dstNo as No, 0 as send, 1 as recv
       from t
       where srcCountry = 'UK' and type = 'RECV'
      )
     ) c
group by country, no;

我应该注意,这将跳过所有值都为0的国家/地区。如果您确实需要这些值,则可以在子查询中包含额外的行。但是,我不清楚发生了No“H”的行,所以我不清楚你真正想要的是什么。

答案 1 :(得分:0)

使用简单的CTE:

WITH config (c) AS (SELECT 'UK'::varchar),
countries (country) AS (
  SELECT srccountry FROM t WHERE srccountry NOT IN (SELECT c FROM config)
  UNION
  SELECT dstcountry FROM t WHERE dstcountry NOT IN (SELECT c FROM config)
),
nos (no) AS (
  SELECT srcno FROM t WHERE srccountry IN (SELECT c FROM config) AND type = 'SEND'
  UNION
  SELECT dstno FROM t WHERE dstcountry IN (SELECT c FROM config) AND type = 'RECV'
),
send (no, country, send) AS (
  SELECT srcno, dstcountry, COUNT(*)
  FROM config LEFT JOIN t ON srccountry = c
  GROUP BY srcno, dstcountry
),
recv (no, country, recv) AS (
  SELECT dstno, srccountry, COUNT(*)
  FROM config LEFT JOIN t ON dstcountry = c
  GROUP BY dstno, srccountry
)
SELECT no, country, COALESCE(send, 0) AS send, COALESCE(recv, 0) AS recv
FROM countries
CROSS JOIN nos
LEFT JOIN send USING (no, country)
LEFT JOIN recv USING (no, country);
  • 配置“表格”只是为了让您不必在查询中的不同位置更改英国;
  • 国家/地区“表格”检索与英国不同的所有国家/地区(或您在配置中放置的任何国家/地区);
  • nos“table”检索英国发送或接收的所有nos;
  • 发送“表格”计算英国发送的每种产品的数量(以及收到的产品);
  • recv“表格”计算英国收到的每件产品的数量(以及谁发送的);
  • 最终查询会加入所有这些结果。