Поворот и суммирование части таблицы SQL

#mysql #sql #stored-procedures #pivot #case

#mysql #sql #хранимые процедуры #поворот #случай

Вопрос:

Привет, я новичок в SQL. У меня есть таблица, подобная этой, и я хочу преобразовать / записать ее в другую таблицу.

 |sessionid |key  |value|
-----------------------
|12345678  |key1 |val1 |
|12345678  |key1 |val2 |
|12345678  |key1 |val3 |
|12345678  |key1 |val4 |
|12345678  |key1 |val5 |
|12345678  |key2 |lav1 |
|12345678  |key2 |lav2 |
|12345678  |key2 |lav3 |
|12345678  |key2 |lav4 |
|12345678  |key3 |lav1 |
|12345678  |key3 |lav2 |
  

и я хочу записать в новую таблицу с этим форматом:

 |sessionid |key1 |key2 |
------------------------
|12345678  |val1 |lav1 |
|12345678  |val2 |lav2 |
|12345678  |val3 |lav3 |
|12345678  |val4 |lav4 |
|12345678  |val5 |null |
  

Что у меня есть, так это:

 SELECT sessionid ,
        
    -- KEY1        
        CASE 
            WHEN logtagname = 'key1' 
            THEN value 
        END AS 'vp_session_id',
        
    -- KEY2        
        CASE 
            WHEN logtagname = 'key2' 
            THEN value 
        END AS 'diy_module',

FROM    table
  

которая возвращает это:

 |sessionid|key1 |key2 |
-----------------------
|12345678 |val1 |null |
|12345678 |val2 |null |
|12345678 |val3 |null |
|12345678 |val4 |null |
|12345678 |val5 |null |
|12345678 |null |lav1 |
|12345678 |null |lav2 |
|12345678 |null |lav3 |
|12345678 |null |lav4 |
  

Кто-нибудь может, пожалуйста, помочь?

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

1. Что, если существует более 2 ключей?

2. @forpas тогда следует игнорировать, я отредактирую свой вопрос, спасибо

Ответ №1:

Таблицы SQL представляют неупорядоченные наборы. Таким образом, вы можете получить значения в отдельных столбцах, используя условную агрегацию (с изюминкой). Но вы не можете контролировать, какие ключевые значения выстраиваются в линию. Для этого вам нужно иметь столбец упорядочения.

Идея заключается в:

 select sessionid,
       max(case when key = 'key1' then value end) key1,
       max(case when key = 'key2' then value end) key2
from (select t.*,
             row_number() over (partition by sessionid, key order by value) as seqnum
      from t
     ) t
group by sessionid, seqnum;
  

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

1. синтаксическая ошибка при использовании near ‘(РАЗДЕЛ ПО идентификатору сеанса…

2. @Soteri . . . Этот синтаксис был доступен в MySQL с версии 8.0, выпущенной около 2,5 лет назад.