Postgres таблица с выбором нескольких столбцов и динамическим преобразованием результата (столбца) в строку - перенос столбца в строки - PullRequest
0 голосов
/ 10 июля 2020

У меня есть структура таблицы (Повреждения) следующего типа

  Rowid    damageTypeACount      damageTypeBCount damageTypeCCount
  1        23                     44              33

А также у меня есть требование прочитать эти строки таблицы с результатом как (заголовок, идентификатор задаются вручную), вроде создания перенос столбцов в строки, но с дополнительными свойствами

  id           damagecountsum          label
    1           23                  Damage Type A
    2           44                  Damage Type B
    3           33                  Damage Type C

Я выполнил следующий запрос, и он работает, но мне интересно, есть ли лучший способ

     SELECT 1 as id,
             damageTypeACount as damagecount,
            "Damage Type A Count" as label
     FROM Damage where rowId=1
      UNION ALL
     SELECT 2 as id,
            damageTypeBCount as damagecount,
            "Damage Type B Count" as label
     FROM Damage where rowId=1
     UNION ALL
     SELECT 3 as id,
           damageTypeCCount as damagecount,
            "Damage Type C Count" as label
     FROM Damage where rowId=1

Приведенный выше запрос работает, как ожидалось, но Мне было интересно, можно ли сделать это в одном операторе выбора, переставляя столбцы в строки

1 Ответ

1 голос
/ 10 июля 2020

Вы можете развернуть с помощью бокового соединения:

select x.*
from damage d
cross join lateral (values
    (d.rowId, d.damageTypeACount, 'Damage Type A'),
    (d.rowId, d.damageTypeBCount, 'Damage Type B'),
    (d.rowId, d.damageTypeCCount, 'Damage Type C')
) as x(id, damagecount, label)

Это влияет на исходный id на каждую сгенерированную строку. Вы также можете сгенерировать новые идентификаторы с помощью row_number():

select row_number() over(order by id, label) id, x.*
from damage d
cross join lateral (values
    (d.rowId, d.damageTypeACount, 'Damage Type A'),
    (d.rowId, d.damageTypeBCount, 'Damage Type B'),
    (d.rowId, d.damageTypeCCount, 'Damage Type C')
) as x(rowId, damagecount, label)

. При необходимости вы можете отфильтровать набор результатов с помощью предложения where:

where d.rowId = 1
...