#postgresql
Вопрос:
У меня возникли проблемы с выполнением разворота в PostgreSQL 12. Мне приходится работать со столом, который сконструирован неловко. Это аналогичная таблица, которую я создал (только для простого представления)-
CREATE TABLE test(Product_num INT, SN INT, Attribute VARCHAR(100), Value DECIMAL, Note VARCHAR(50) );
Следующим шагом был импорт CSV-файла с помощью функции КОПИРОВАНИЯ-
COPY public.test from 'C:File Locationtest.csv' DELIMITER ',' csv HEADER;
Я получаю таблицу с более чем 30 тыс. строк, которая выглядит так-
Product_num | SN | Attribute | Value | Note |
100 9225 Unit sold 50 USA
100 9225 Unit price 4.99
100 9225 Num_boxes 2.5
101 9226 Unit sold 1 GER
101 9226 Unit price 920
101 9226 Num_boxes 2
Я хочу получить таблицу, похожую на следующую таблицу-
Product_num | SN | Unit Sold | Unit price | Num_boxes | Note
100 | 9225 | 50 | 4.99 | 2.5 | USA
101 | 9226 | 1 | 920 | 2 | GER
Я попробовал несколько методов, включая crosstab (), а также попытался объединить несколько столбцов, но столкнулся с некоторыми проблемами.
В таблице есть некоторые вопросы, которые необходимо принять во внимание-
- Столбец атрибутов не идентичен для каждого SN — это означает, что каждый SN имеет разные атрибуты, некоторые идентичные, а некоторые нет.
- Существует множество нулевых значений.
- Существует множество значений 0.
Надеюсь, мне удалось объясниться как можно лучше, спасибо
Ответ №1:
Я бы объединил все атрибуты в структуру JSON, а затем извлек их в окончательном запросе:
select product_num, sn,
(attributes ->> 'Num_boxes')::decimal as num_boxes,
(attributes ->> 'Unit sold')::decimal as unit_sold,
(attributes ->> 'Unit price')::decimal as unit_price,
note
from (
select product_num, sn, max(note) as note,
jsonb_object_agg(attribute, value) as attributes
from test
group by product_num, sn
) t
order by product_num, sn;
Если будут добавлены новые атрибуты, вам потребуется расширить внешний список выбора, чтобы отразить это. Невозможно создать динамический список столбцов без изменения запроса. В SQL число и типы столбцов запроса должны быть известны до запуска инструкции.
Комментарии:
1. Это хорошее решение, спасибо! У меня около 40 атрибутов, так что добавить больше вручную не проблема
Ответ №2:
Я предложу таким образом:
Сначала выполните приведенный ниже запрос:
select distinct (attribute) from test;
Вы получите все атрибуты из приведенного выше запроса:
Теперь добавьте все атрибуты в приведенный ниже запрос, чтобы получить свой результат:
select
product_num,
sn,
coalesce(max(value) filter (where attribute ='Unit sold'),0) as "Unit Sold",
coalesce(max(value) filter (where attribute ='Unit price'),0) as "Unit Price",
coalesce(max(value) filter (where attribute ='Num_boxes'),0) as "Num_boxes",
.
.
coalesce(max(note),'')
from test
group by 1,2
вы ilike
также можете использовать условие фильтра, если хотите, чтобы значения совпадали, игнорируя регистр.