Добавить значения в SQL - PullRequest
       12

Добавить значения в SQL

0 голосов
/ 04 декабря 2018

предположим, у меня есть следующая таблица.

У меня возникает следующая проблема при добавлении значений, расположенных в разных строках.

rankk val price
1   A   10
2   B   20
3   C   30

Как получить эти результаты?

rank val2
1    A
2    A,B
3    A,B,C

Я застрял с

rank val2
1    A
2    ,B
3    ,C

create multiset volatile table tmp_db (
rankk integer,
val varchar(1),
price integer)
primary index (val) on commit preserve rows;

insert into tmp_db values (1,'A',10);
insert into tmp_db values (2,'B',20);
insert into tmp_db values (3,'C',30);

sel rankk,
        max(case when rankk = 1 then val else '' end) ||
        max(case when rankk = 2 then ',' || val else '' end) ||
        max(case when rankk = 3 then ',' || val else '' end) as val2,
        avg(price) as avg_price

from   tmp_db
group by 1;

Заранее благодарим за неудобства.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Попробуйте использовать рекурсивный cte

with combo_data
  as (select rankk,val, cast(val as varchar(100)) as val2
        from tmp_db 
       where rankk=1
      union all
      select b.rankk,b.val,cast(concat(b.val,',',a.val2) as varchar(100))
        from tmp_db b
        join combo_data a
          on a.rankk+1=b.rankk
      )
select rankk,val2
  from combo_data
0 голосов
/ 04 декабря 2018

Вам необходимо самообъединение, подобное этому

SEL t1.rankk,
        Max(CASE WHEN t2.rankk = 1 THEN t2.val ELSE '' end) ||
        Max(CASE WHEN t2.rankk = 2 THEN ',' || t2.val ELSE '' end) ||
        Max(CASE WHEN t2.rankk = 3 THEN ',' || t2.val ELSE '' end) AS val2,
        Avg(t2.price) AS avg_price

FROM tmp_db AS t1 JOIN tmp_db AS t2 
  ON t1.rankk >= t2.rankk -- include all previous rows
GROUP BY 1;

Для более высоких рангов также можно использовать xmlagg (это добавит пробел между значениями):

SELECT t1.rankk,
   Trim(Trailing ',' FROM 
       (XmlAgg(Trim(t2.val)|| ',' ORDER BY t2.val DESC) (VARCHAR(1000)))) AS val,
  Avg(t2.price) AS avg_price
FROM tmp_db AS t1 JOIN tmp_db AS t2 
  ON t1.rankk >= t2.rankk
GROUP BY 1

В зависимости от ваших реальных данных вы также можете использовать рекурсию:

WITH RECURSIVE cte AS 
 (
   SELECT rankk, val, Cast(val AS VARCHAR(1000)) AS rslt, price
   FROM tmp_db
   WHERE rankk = 1 -- start with 1st rank
   UNION ALL
   SELECT t.rankk, t.val,
      cte.rslt || ',' || t.val AS rslt,
      cte.price + t.price -- to calculate average using sum/rankk
   FROM tmp_db AS t JOIN cte
   ON t.rankk = cte.rankk+1
 )
SELECT rankk, rslt, price / rankk 
FROM cte
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...