Postgres Возвращает HTML теги таблицы, сгруппированные по столбцу для набора результатов - PullRequest
1 голос
/ 10 июля 2020

Я пытаюсь создать функцию, которая генерирует теги row и cell HTML, которые будут использоваться в другом приложении для создания базовой c HTML таблицы. Строку и ячейки необходимо сгруппировать / объединить по идентификатору региона. Это та часть, с которой я сейчас борюсь.

enter image description here

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

Я попытался собрать следующую функцию вместе, но не совсем уверен, куда go, чтобы гарантировать, что вывод правильно сгруппирован по region_id.

Это не что-то, что я обычно делал бы SQL, но я работаю с некоторыми ограниченными технологиями.


create table reporting
(
    id integer,
    region_id integer,
    category text,
    item text,
    status text
);


insert into reporting values
   (1, 1, 'audio', 'speakers', 'delivered'),
   (2, 1, 'display', 'monitors', 'pending'),
   (3, 2, 'cables', 'hdmi', 'pre-order'),
   (4, 3, 'storage', 'sdd', 'cancelled'),
   (5, 3, 'software', 'business', 'delivered'),
   (6, 3, 'other', 'support', 'delivered');


create function html_out (query text)
returns  TABLE(region_id text, result text) language plpgsql as $$
declare
    rec record;
    header boolean := true;
begin
    for rec in
        execute format($q$
            select row_to_json(q) json_row
            from (%s) q
            $q$, query)
    loop
        return query select region_id,
            format ('<tr><td>%s</td></tr>', string_agg(value, '</td><td>'))
        from json_each_text(rec.json_row);
    end loop;
end $$;

select html_out('select region_id, category, item, status from reporting');


Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Если речь идет об объединении повторения region_id с rowspan=, то вы можете получить это в одном go вот так:

with consolidate as (
  select region_id, concat('<td rowspan="', count(*), '">') as rowspan 
    from reporting
   group by region_id
), trows as (
  select row_number() over (order by r.region_id, r.id) as rnum,
         concat(
           '<tr>',
           case 
             when lag(c.region_id) over w = c.region_id then ''
             else concat(c.rowspan, c.region_id, '</td>')
           end,
           '<td>', 
           array_to_string(array[r.category, r.item, r.status]::text[], '</td><td>', '</td>'),
           '</tr>'
         ) as html
    from consolidate c
    join reporting r on r.region_id = c.region_id
  window w as (partition by r.region_id order by r.id)
)
select array_to_string(array_agg(html order by rnum), ' 
')
  from trows;
-[ RECORD 1 ]---+-----------------------------------------------------------------------------
array_to_string | <tr><td rowspan="2">1</td><td>audio</td><td>speakers</td><td>delivered</tr> +
                | <tr><td>display</td><td>monitors</td><td>pending</tr>                       +
                | <tr><td rowspan="1">2</td><td>cables</td><td>hdmi</td><td>pre-order</tr>    +
                | <tr><td rowspan="3">3</td><td>storage</td><td>sdd</td><td>cancelled</tr>    +
                | <tr><td>software</td><td>business</td><td>delivered</tr>                    +
                | <tr><td>other</td><td>support</td><td>delivered</tr>


Я поставил новую строку в качестве разделителя для последнего array_to_string() просто чтобы он выглядел красиво. ' ' или '', вероятно, будет тем, что вам нужно.

0 голосов
/ 10 июля 2020

Вы можете использовать агрегирование строк. Я думаю, что logi c, который вам нужен:

select
    region_id,
    '<tr><td>' 
    || string_agg(concat_ws('</td><td>', category, item, status), '</td></tr><tr><td>')
    || '</td></tr>' html
from reporting
group by region_id
order by 1

Демо на DB Fiddle

region_id | html                                                                                                                                                                     
--------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        1 | <tr><td>audio</td><td>speakers</td><td>delivered</td></tr><tr><td>display</td><td>monitors</td><td>pending</td></tr>                                                         
        2 | <tr><td>cables</td><td>hdmi</td><td>pre-order</td></tr>                                                                                                                      
        3 | <tr><td>storage</td><td>sdd</td><td>cancelled</td></tr><tr><td>software</td><td>business</td><td>delivered</td></tr><tr><td>other</td><td>support</td><td>delivered</td></tr>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...