запрос для транспонирования строк в столбцы SQLite - PullRequest
0 голосов
/ 26 октября 2019

Добрый день, я хотел бы знать, можно ли сделать запрос для генерации столбцов в соответствии с количеством строк в моей таблице

example:

      ID       COD    DIAG
    111111111 | Z359 |  D   
    111111112 | Z359 |  D   
    111111112 | Z359 |  D   
    111111113 | Z359 |  R   
    111111113 | Z359 |  P   
    111111113 | Z359 |  R   
    111111114 | Z359 |  D   
    111111114 | Z359 |  D   
    111111114 | Z359 |  D   
    111111115 | Z359 |  D   


it would be ideal that columns be created according to the number of rows for each id, if not possible it would put a fixed number of columns.

    result query

        ID    | COD1 | DIAG1 | COD2 | DIAG2 | COD3 | DIAG3 
    111111111 | Z359 |   D   |      |       |      | 
    111111112 | Z359 |   D   | Z359 |   D   |      |
    111111113 | Z359 |   R   | Z359 |   P   | Z359 |  R
    111111114 | Z359 |   D   | Z359 |   D   | Z359 |  D
    111111115 | Z359 |   D   |      |       |      | 

извините, мой английский

Большое спасибо !!

1 Ответ

0 голосов
/ 26 октября 2019

Этот первый запрос следует шаблону ответа на дублирующий вопрос , включенного здесь для сравнения.

WITH numbered AS (
     SELECT row_number() OVER 
                 (PARTITION BY ID ORDER BY COD, DIAG) 
                 AS seq,
            t.*
     FROM SO58566470 t)
SELECT ID,
       max(CASE WHEN seq = 1 THEN COD END) AS COD1,
       max(CASE WHEN seq = 1 THEN DIAG END) AS DIAG1,
       max(CASE WHEN seq = 2 THEN COD END) AS COD1,
       max(CASE WHEN seq = 2 THEN DIAG END) AS DIAG1,
       max(CASE WHEN seq = 3 THEN COD END) AS COD3,
       max(CASE WHEN seq = 3 THEN DIAG END) AS DIAG3
FROM numbered n
GROUP BY ID;

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

Следующий запрос выглядит длиннее ивозможно, более сложный, но он использует преимущества секционированных данных (то есть данных окна), собирая преобразованные значения в одном и том же процессе. Но поскольку оконные функции обязательно работают с каждой строкой, возникает необходимость отфильтровывать «неполные» строки. Я не проводил никакого профилирования по запросам, но подозреваю, что этот второй запрос в целом гораздо эффективнее.

WITH transform AS (
    SELECT id,
           lag(COD, 0)  OVER IDWin AS COD1,           
           lag(DIAG, 0) OVER IDWin AS DIAG1, 
           lag(COD, 1)  OVER IDWin AS COD2,
           lag(DIAG, 1) OVER IDWin AS DIAG2,
           lag(COD, 2)  OVER IDWin AS COD3,
           lag(DIAG, 2) OVER IDWin AS DIAG3,       
           row_number() OVER IDWin AS seq
    FROM SO58566470 t
    WINDOW IDWin AS (PARTITION BY ID ORDER BY COD, DIAG)
    ORDER BY ID, SEQ
  ),
  last AS (
    SELECT id, max(seq) as maxseq
    FROM transform
    GROUP BY id
  )
SELECT transform.*
FROM transform 
     JOIN last 
       ON transform.id = last.id AND transform.seq = last.maxseq
ORDER BY id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...