Старый поток, но, да ... в Oracle есть способ сделать это:
with
employee(id, firstname, lastname, hobbies) as
(
select 1, 'a', 'b', '1' from dual union
select 2, 'a', 'b', '2' from dual union
select 3, 'a', 'b', '3' from dual union
select 4, 'c', 'd', '3' from dual union
select 5, 'e', 'f', '2' from dual
)
select *
from employee
pivot
(
max(1) -- fake
for (hobbies) -- put the undesired columns here
IN () -- no values here...
)
where 1=1 -- and your filters here...
order by id
Чтобы понять, как работает PIVOT и почему он решает вопрос, давайте рассмотрим лучший пример для нашей таблицы employee
:
select *
from employee
pivot
(
max(id) foo,
max(1) bar
for (hobbies)
IN ('2' as two, '3' as three)
)
Результат здесь:
FIRSTNAME | LASTNAME | TWO_FOO | TWO_BAR | THREE_FOO | THREE_BAR
c d null null 4 1
e f 5 1 null null
a b 2 1 3 1
Точно такой же вывод можно получить с помощью этого более простого для понимания запроса:
select
firstname,
lastname,
max(case when hobbies = '2' then id end) two_foo,
max(case when hobbies = '2' then 1 end) two_bar,
max(case when hobbies = '3' then id end) three_foo,
max(case when hobbies = '3' then 1 end) three_bar
from employee
group by
firstname,
lastname
Таким образом, столбец hobbies
никогда не выбирается, как столбец id
, оба указаны в предложении PIVOT . Все остальные столбцы сгруппированы и выделены.
Что касается первого запроса, он работает по двум причинам:
1- вы не потеряете ни одной строки в процессе группировки, поскольку столбец id является уникальным и столбцы для агрегатов не указаны;
2 - поскольку сводная система генерирует N * M новых столбцов, где N = количество значений предложения IN и M = количество указанных агрегаций, поэтому отсутствие фильтров и единственная безвредная агрегация приведут к 0 * 1 = 0 новых столбцов и удалит те, которые указаны в предложении PIVOT , которое является просто хобби .
ОТВЕТЬТЕ НА КОММЕНТАРИЙ 1
Первая строка этого вопроса гласит: "... без указания нужных полей" . Во всех остальных ответах предложенные запросы указывают нужные поля в предложении SELECT , за исключением моего, фактически.
Также в названии вопроса написано "... без писательской спазма" . Ну, как правильно определить судьбу писателя? Я приложил бы все усилия, чтобы предвидеть хороший стандарт SQL для этой проблемы и сравнить с моим ответом. На самом деле, я думаю, что этот «стандарт» может выглядеть примерно так: SELECT * NOT IN ([col1], [col2], ...) .
Теперь я могу видеть в обоих запросах:
- список нежелательных столбцов;
- и IN предложение;
- предложение из трех символов - FOR и NOT ;
Это означает, что вам нужно написать немного больше в моем подходе, так как вам нужно поддельное агрегирование и предложение PIVOT ... но на самом деле это всего лишь несколько символов ...