Postgresql – How to pivot a table skipping bad value in Postgres

postgresqlwindow functions

Given a table like:

 label |   x   |   y   |   z 
-------+-------+-------+------
 AAA   | NULL  |   7   |   9
 BBB   | 0     |  10   |   0
 CCC   | 12    | NULL  |   0

create table coords (label text, x integer, y integer, z integer);
insert into coords(label,x,y,z)
values
    ('AAA',NULL,7,9),
    ('BBB',0,10,0),
    ('CCC',12,NULL,0);

I need to insert in another table values by label when they are not NULL or 0s.
So the final result will be:

label | coord | value |
------+-------+-------+
AAA   |   y   |  7    |
AAA   |   z   |  9    |
BBB   |   y   |  10   |
CCC   |   x   |  12   |

I tried with different OVER/PARTITION but probably I am missing something. Any help?

Best Answer

This is really straight forward:

INSERT INTO new_table 
    (label, coord, value)
SELECT label, 'x', x  FROM coords  WHERE x <> 0 
UNION ALL
SELECT label, 'y', y  FROM coords  WHERE y <> 0 
UNION ALL
SELECT label, 'z', z  FROM coords  WHERE z <> 0 ;

or using LATERAL:

INSERT INTO new_table 
    (label, coord, value)
SELECT c.label, v.coord, v.value  
FROM coords AS c
    , LATERAL 
     ( VALUES ('x', x),
              ('y', y),
              ('z', z)
     ) AS v (coord, value)
WHERE v.value <> 0 ;