Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Getting ratio of summed columns

I have the following DB structure.

id projectname number filename type unq count
8 prj1 2 a t1 888389f661e117 1
9 prj1 2 a t1 888389f661e117 2
10 prj1 2 a t1 888389f661e117 2
11 prj1 2 a t2 816418549711c3d33 6
12 prj1 2 a t2 816418549711c3d33 7
13 prj1 2 a t2 816418549711c3d33 1
14 prj1 2 a t3 NULL NULL
15 prj1 2 a t3 NULL NULL
16 prj1 2 a t3 NULL NULL
17 prj1 36 b t1 8dac5bdffc7f86502 0
18 prj1 36 b t1 8dac5bdffc7f86502 0
19 prj1 36 b t1 8dac5bdffc7f86502 0

I use the query below to get the sums of count column w.r.t. the type column. A unique identifier of a row is `(projectname, number, filename).

SELECT DISTINCT ON (projectname, number, type) number, type, SUM(count) as count
FROM myTable
GROUP BY (projectname, number, type)
ORDER BY number

which gives me the output

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

number type count
2 t1 5
2 t2 14
2 t3 NULL
36 t1 0
36 t2 16
36 t3 NULL

My ideal output is: for every number column item, I want to divide the t2 value by t1 and the t3 value to t2. Can I accomplish this with Postgres commands without using external data manipulation techniques? I am looking to obtain a table as below. The type column is just representative of the operation I am interested in.

number type ratio
2 t2t1 14 by 5
2 t3t2 NULL by 14 is NULL
36 t2t1 16 by 0 is INF
36 t3t2 NULL by 16 is NULL

>Solution :

Based on your which gives me the output we can try to use LEAD and ROW_NUMBER window function to get next count and filter the latest row each number

SELECT number,
       type,
       CASE WHEN count = 0 THEN 'INF' ELSE (n_count::DECIMAL(8,3) /count )::VARCHAR(20) END
FROM (
  SELECT *,
        LEAD(count) OVER(PARTITION BY number ORDER BY type) n_count,
        ROW_NUMBER() OVER(PARTITION BY number ORDER BY type DESC) rn 
  FROM (
    SELECT DISTINCT ON (projectname, number, type) number, type, SUM(count) as count
    FROM myTable
    GROUP BY (projectname, number, type)
    ORDER BY number
  ) t1
) t1
WHERE rn > 1

but I saw full sample data and expect result you might need to use OUTER JOIN based on type,number which is created by CROSS JOIN

WITH CTE AS (
 SELECT *
 FROM (
  SELECT distinct type
  FROM myTable
 ) t1 CROSS JOIN (
  SELECT distinct number
  FROM myTable
 ) t2
)
SELECT number,
       type,
        CASE WHEN count = 0 THEN 'INF' ELSE (n_count::DECIMAL(8,3) /count )::VARCHAR(20) END
FROM (
  SELECT *,
        LEAD(count) OVER(PARTITION BY number ORDER BY type) n_count,
        ROW_NUMBER() OVER(PARTITION BY number ORDER BY type DESC) rn 
  FROM (
    SELECT t1.number, t1.type, SUM(t2.count) count
    FROM CTE t1
    LEFT JOIN myTable t2
    ON t1.type = t2.type
    AND t1.number = t2.number
   GROUP BY t1.number, t1.type
  ) t1
) t1
WHERE rn > 1

sqlfiddle

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading