How do I substract values from an UNION query in POSTGRESQL?

时间:2018-09-18 19:52:11

标签: sql postgresql union

My UNION query is:

SELECT type, hs
FROM (...) as table_1

UNION

SELECT type, hs
FROM (...) as table_2

UNION 

SELECT type, hs
FROM (...) as table_3

What i want to do is:

SELECT 
table_1.hs hs_1, 
table_2.hs hs_2,
table_3.hs - (table_1.hs + table_2.hs) hs_3
FROM ()

Just tell me if I have explained myself correctly.

** Edited

As asked, I add more details:

Rows from UNION of all 3 tables are:

type   | hs
___________
'BLUE' | 8
'RED'  | 2
'ALL'  | 15

What i need is:

type   | hs
___________
'BLUE' | 8
'RED'  | 2
'REST' | 5

'REST' value is obtained from substracting the addition of 'RED' (2) + 'BLUE' (8) from ALL (15)

In Postgresql, something like:

SELECT 
table_1.hs hs_1, 
table_2.hs hs_2,
table_3.hs - (table_1.hs + table_2.hs) hs_3
FROM ()

1 个答案:

答案 0 :(得分:2)

You can try to use CTE to get the UNION result set. then use CASE WHEN and subquery make your logic.

Schema (PostgreSQL v9.6)

CREATE TABLE T1(
   type varchar(50),
  hs int
);

CREATE TABLE T2(
   type varchar(50),
  hs int
);

CREATE TABLE T3(
   type varchar(50),
  hs int
);




INSERT INTO T1 VALUES ('BLUE',8);
INSERT INTO T2 VALUES ('RED' , 2);
INSERT INTO T3 VALUES ('ALL' , 15);

Query #1

WITH CTE AS (

  SELECT type, hs
   FROM T1
   UNION
   SELECT type, hs
   FROM T2
   UNION 
   SELECT type, hs
   FROM T3
)
SELECT CASE WHEN type = 'ALL' 
             THEN 'REST'
          ELSE type END,
          CASE WHEN type = 'ALL' 
             THEN hs - (SELECT SUM(hs) FROM CTE WHERE type in ('RED','BLUE'))
          ELSE hs END
FROM CTE;

| type | hs  |
| ---- | --- |
| RED  | 2   |
| REST | 5   |
| BLUE | 8   |

View on DB Fiddle