Как ОТКЛЮЧИТЬ несколько столбцов в более чем два столбца? - PullRequest
0 голосов
/ 29 июня 2018

У меня есть данные в базе данных SybaseASE 15.X, и я пытаюсь запросить аккуратные данные. Данные структурированы так в таблице Sybase:

| Name | Foo_A | Foo_B | Foo_C | Bar_A | Bar_B | Bar_C |
--------------------------------------------------------
| abcd |    16 |    32 |    14 |    52 |    41 |    17 |
| ...  |   ... |   ... |   ... |   ... |   ... |   ... |

Я ищу запрос данных таким образом, чтобы они выглядели так:

| Name | Class | FooVal | BarVal |
----------------------------------
| abcd | A     |     16 |     52 |
| abcd | B     |     32 |     41 |
| abcd | C     |     14 |     17 |
| ...  | ...   |    ... |    ... |

Теперь я уже знаю и использую UNION ALL, но , что было бы более кратким и простым способом делать то, что кажется простым UNPIVOT?

Как я уже читал на этом веб-сайте, документацию MSDN, документацию SAP и ссылки на SQL, UNPIVOT предназначен только для вывода в две колонки.

Если есть какая-либо дополнительная информация, которая будет полезна, пожалуйста, дайте мне знать. Спасибо!

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Sybase (теперь SAP) ASE не имеет возможности unpivot (как вы, вероятно, уже знаете) и не поддерживает векторные функции (которые могут обеспечить операцию разделения строк от 1 до многих).

В дополнение к решению union all от Yogesh вы можете посмотреть на производительность для перекрестного объединения (декартово произведение) с псевдотаблицей из 3 строк (при условии, что у вас есть только 3 класса), например:

-- setup

create table mytable(Name varchar(10), Foo_A int, Foo_B int, Foo_C int, Bar_A int, Bar_B int, Bar_C int)
go

insert mytable values ('abcd',16,32,14,52,41,17)
go

-- main query

select  m.Name,
        p.Class,
        case when p.Class = 'A' then m.Foo_A
             when p.Class = 'B' then m.Foo_B
             when p.Class = 'C' then m.Foo_C
        end as FooVal,
        case when p.Class = 'A' then m.Bar_A
             when p.Class = 'B' then m.Bar_B
             when p.Class = 'C' then m.Bar_C
        end as BarVal

from    mytable m,
        (select 'A' as Class
         union all
         select 'B'
         union all
         select 'C') p

order by m.Name, p.Class
go

 Name       Class FooVal      BarVal
 ---------- ----- ----------- -----------
 abcd       A              16          52
 abcd       B              32          41
 abcd       C              14          17

Чтобы понять, как это работает, выполните следующее, чтобы увидеть набор результатов, сгенерированный соединением, затем примените логику case, чтобы увидеть, как генерируются окончательные строки:

select  p.Class, m.*
from    mytable m,
        (select 'A' as Class
         union all
         select 'B'
         union all
         select 'C') p
order by m.Name, p.Class
go
0 голосов
/ 29 июня 2018

Использование UNION ALL:

select t.*
from (select Name, 'A' as Class, Foo_A as FooVal, Bar_A as BarVal
      from table 
      union all
      select Name, 'B', Foo_B, Bar_B
      from table 
      union all
      select Name, 'C', Foo_C, Bar_C
      from table
     ) t
order by name;
...