Как выбрать последние три столбца, отличных от NULL, в нескольких столбцах - PullRequest
1 голос
/ 03 мая 2020

Например, если мой набор данных выглядит следующим образом:

id | col1 | col2 | col3 | col4 | col5 | col6
---+------+------+------+------+------+-----
 A | a1   | a2   | a3   | a4   | a5   | a6
 B | b1   | b2   | b3   | b4   | NULL | NULL
 C | c1   | c2   | c3   | NULL | NULL | NULL

Желаемый результат будет:

id | col1 | col2 | col3 | col4 | col5 | col6
---+------+------+------+------+------+-----
 A | a4   | a5   | a6   |
 B | b2   | b3   | b4   |
 C | c1   | c2   | c3   |  

Кто-нибудь знает, как этого добиться?

Я только что нашел эту тему: https://dba.stackexchange.com/questions/210431/select-first-and-last-non-empty-blank-column-of-a-record-mysql

Это позволяет мне выбрать последний ненулевой столбец, но я понятия не имею, чтобы получить второй и третий последний столбец в в то же время.

Ответы [ 2 ]

3 голосов
/ 03 мая 2020

Это будет делать то, что вы запрашиваете ( db <> fiddle )

Редактировать: Первоначальная версия, вероятно, не сделала то, что вы хотите, если их было меньше чем три NOT NULL значения подряд. Эта версия сместит их влево.

SELECT Id,
       CA.Col1,
       CA.Col2,
       CA.Col3,
       NULL AS Col4,
       NULL AS Col5,
       NULL AS Col6
FROM   YourTable
       CROSS APPLY (SELECT MAX(CASE WHEN RN = 1 THEN val END) AS Col1,
                           MAX(CASE WHEN RN = 2 THEN val END) AS Col2,
                           MAX(CASE WHEN RN = 3 THEN val END) AS Col3
                    FROM   (SELECT val,
                                   ROW_NUMBER() OVER (ORDER BY ord) AS RN
                            FROM                    
                               (SELECT TOP 3 *
                                FROM   (VALUES(1, col1),
                                              (2, col2),
                                              (3, col3),
                                              (4, col4),
                                              (5, col5),
                                              (6, col6) ) v(ord, val)
                                WHERE  val IS NOT NULL
                                ORDER BY ord DESC
                                ) d1                            
                            ) d2                            
                    ) CA 
1 голос
/ 03 мая 2020

Вы также можете использовать pivot и unpivot для достижения желаемого результата.

попробуйте следующее:

;with cte as 
(
    select id, cols, col as val, ROW_NUMBER() over (partition by id order by cols desc) rn
    from @t
    unpivot
    (
        col for cols in ([col1], [col2], [col3], [col4], [col5], [col6])
    )upvt
)
select id, ISNULL([3], '') as col1, ISNULL([2], '') as col2, ISNULL([1], '') as col3, '' col4, '' col5, '' col6
from 
(
    select id, val, rn from cte
)t
pivot
(
    max(val) for rn in ([1], [2], [3])
)pvt
order by 1

Пожалуйста, найдите db <> fiddle здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...