简体   繁体   中英

Reshape result set from wide to long table in postgres and improve query

I wrote the following query to obtain the number of missing values from all columns in a table. But that return the result set in a wide shape table:

1) I need the result set reshaped in long format.
2) It is possible to improve the query to write a simpler one?

The query:

-- Variable to save the row count from the table
WITH total_rows AS 
    (
    SELECT COUNT(*) AS rows
    FROM table_name
    )

-- Query to join subqueries (wide table format)
SELECT
    *
FROM

-- Subquery1
    (SELECT
        (SELECT rows FROM total_rows) - COUNT(colum1) AS missing_colum1 -- counts all values except nulls
    FROM table_name
    ) AS missing_values_colum1,

-- Subquery2    
    (SELECT
        (SELECT rows FROM total_rows) - COUNT(colum2) AS missing_colum2
    FROM table_name
    ) AS missing_values_colum2,

-- Subquery3   
    (SELECT
        (SELECT rows FROM total_rows) - COUNT(colum3) AS missing_colum3
    FROM table_name
    ) AS missing_values_colum3,

-- Subquery4    
    (SELECT
        (SELECT rows FROM total_rows) - COUNT(colum4) AS missing_colum4
    FROM table_name
    ) AS missing_values_colum4
;

Any tip will help. Thank you in advance.

It's not completely clear to me what you want to achieve.

But for starters your existing query can be simplified to:

select count(*) as total_rows, 
       count(*) - count(column1) as missing_column1,
       count(*) - count(column2) as missing_column2,
       count(*) - count(column3) as missing_column3,
       count(*) - count(column3) as missing_column4
from table_name

In case you are worried: count(*) will only be evaluated once, not five times.

If you want the numbers for each column as rows ("long format"?) rather than columns ("wide format") you can unpivot the result from the above:

with totals as (
  select count(*) as total_rows, 
         count(*) - count(column1) as missing_column1,
         count(*) - count(column2) as missing_column2,
         count(*) - count(column3) as missing_column3,
         count(*) - count(column3) as missing_column4
  from table_name
)
select t.total_rows, m.col_name, m.num_missing
from totals t
  cross join lateral (
    values ('column1', missing_column1),
           ('column2', missing_column2),
           ('column3', missing_column3),
           ('column4', missing_column4)
  ) as m(col_name, missing);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM