Home > OS >  Converting the header row to a column PostgreSQL
Converting the header row to a column PostgreSQL

Time:03-08

I am new to PostgreSQL. I have a table with three columns as mentioned below and i want to convert the header row to a column with the corresponding values in another column and finally a new column that checks if the value is missing or not.

ID   NAME   EMAIL            SALARY
1    John   ''               1000
2    Sam    [email protected]   6000
3    Tom    [email protected]   9000
4    Bob    [email protected]    500
5    Lari   [email protected]   3000

The expected output for each ID:

ID   fields      Value            Verified
 1    NAME        John              Yes
      EMAIL        ''               No
      SALARY      1000              Yes

 2    NAME        Sam               Yes
      EMAIL      [email protected]     Yes
      SALARY      6000              Yes

CodePudding user response:

Another option is to use a CROSS JOIN with a VALUES clause that transposes the columns into rows:

select t.id, 
       u.*,
       case 
         when u.value = '' or u.value is null then 'No'
         else 'Yes'
       end as verified
from the_table t
  cross join lateral (
     values ('NAME', name), ('EMAIL', email), ('SALARY', salary::text)
  ) as u(column_name, value)
order by t.id, u.column_name  

This is shorter to write and easier to maintain, but I have seen the UNION ALL approach from Thorsten Kettner to be faster in some situations.

CodePudding user response:

What you call the header row is no row at all, but just the column names. You want one row per ID and column. While this is something I'd rather do in the app and not in SQL, it is possible of course. You need one query per column. Glue their results together with UNION ALL.

select
  id, 
  'NAME' as fields,
  name as value,
  case when name is null or name = '' then 'No' else 'Yes' as verified
from mytable
union all
select
  id, 
  'EMAIL' as fields,
  email as value,
  case when email is null or email = '' then 'No' else 'Yes' as verified
from mytable
union all
select
  id, 
  'SALARY' as fields,
  cast(salary as varchar) as value,
  case when salary is null then 'No' else 'Yes' as verified
from mytable
order by id, fields;

But as mentioned, it would be better just to select * from mytable and care about the presentation of the data in your app. This is probably much faster, too.

  • Related