Отключение в PostgreSQL с нулевым значением

#postgresql

#postgresql

Вопрос:

Я делаю отключение преобразования из Oracle в postgres. У меня следующая проблема: в Oracle отключение автоматически удаляется с нулевым значением, но postgres завершается с ошибкой.Как сделать Postgres таким же, как Oracle, вы можете мне помочь?

Oracle:

 with detail as (                
    select          
        'A1' as a,      
        'A2' as b,      
        'A3' as c,      
        null as d       
    from dual           
)               
select * from detail unpivot (              
    agg_value for (agg_name) in (           
        a as 'Max Concurrent Users',        
        b as 'Max Concurrent User Time',        
        c as 'Min Concurrent Users',        
        d as 'Min Concurrent User Time'     
    )           
);
  

Результат Oracle:

введите описание изображения здесь

Postgres:

 WITH detail AS (                        
    select                  
        'A1' as a,              
        'A2' as b,              
        'A3' as c,              
        null as d               
)                       
SELECT * FROM (                     
    SELECT 
        unnest(array['Max Concurrent Users', 'Max Concurrent User Time', 'Min Concurrent Users', 'Min Concurrent User Time']) AS agg_name,
        unnest(array[a, b, c, d]) AS agg_value
    FROM
        detail
) foo;
  

Результат postgres:

введите описание изображения здесь

Комментарии:

1. Ваша проверка орфографии барахлит? У вас есть «Univot» (отсутствует «p») как минимум в трех местах.

Ответ №1:

Вы можете использовать WHERE предложение следующим образом: (Я приложил запрос Oracle, вы можете использовать то же WHERE предложение в Postgress)

 WITH DETAIL AS (
    SELECT 'A1' AS A,
           'A2' AS B,
           'A3' AS C,
           NULL AS D
      FROM DUAL
)
SELECT *
  FROM DETAIL UNPIVOT ( AGG_VALUE
    FOR ( AGG_NAME )
IN ( A AS 'Max Concurrent Users',
     B AS 'Max Concurrent User Time',
     C AS 'Min Concurrent Users',
     D AS 'Min Concurrent User Time' ) )
 WHERE AGG_VALUE IS NOT NULL; -- ADD THIS CONDITION
  

Ответ №2:

Я предпочитаю боковое соединение против предложения values для реализации unpivot в Postgres:

 WITH detail (a,b,c,d) AS (                        
  values ('A1', 'A2', 'A3', null)
)                       
SELECT u.*
FROM detail d
  cross join lateral (
    values 
        (a, 'Max Concurrent Users'),
        (b, 'Max Concurrent User Time'),
        (c, 'Min Concurrent Users'),
        (d, 'Min Concurrent User Time')
  ) as u (col, col_name)
where u.col is not null;  
  

Если имена столбцов в таблице являются «читаемыми», вы можете упростить это, используя JSON:

 select u.*
from detail d
  cross join jsonb_each_text(to_jsonb(d)) as u(col_name, col);