#sql #oracle
#sql #Oracle
Вопрос:
У меня есть запрос, который возвращает что-то вроде этого…
Набор данных 1:
EFFECTIVE_DATE END_DATE DESC SUBPART
4/10/2011 Dairy Products Processing L
4/10/2011 360 CMR 10.000
4/1/2011 4/9/2011 Dairy Products Processing A
4/1/2011 4/9/2011 Ferroalloy Manufacturing A
Я хочу получить запрос, который возвращает этот набор данных следующим образом…
Набор данных 2:
EFFECTIVE_DATE END_DATE DESC SUBPART
4/10/2011 Dairy Products Processing L
360 CMR 10.000
4/1/2011 4/9/2011 Dairy Products Processing A
Ferroalloy Manufacturing A
Обратите внимание, что повторяющиеся даты вступления в силу (4/10/2011 — {null} и 4/1/2011 — 4/9/2011) при дублировании подавляются.
Редактировать 1: В ответ на ответ @ Justin Cave,
Ниже приведен мой запрос, объединенный с шаблоном Джастина Кейва. Это близко, но немного не так. Даты и описания кажутся немного не такими, какими они должны быть (данные в наборе данных должны быть такими же, как в наборе данных 2:. Я думаю, что это может иметь какое-то отношение к моему порядку, но я не уверен.
SELECT (CASE WHEN effective_date = prior_effective_date
THEN null
ELSE effective_date
END) effective_date,
(CASE WHEN end_date = prior_end_date
THEN null
ELSE end_date
END) end_date,
cfr_part_desc ,
cfr_subpart
FROM
(SELECT c.effective_date,
lag(c.effective_date) over (order by c.effective_date desc, cpl.cfr_part_desc asc) prior_effective_date,
c.end_date,
lag(c.end_date) over (order by c.effective_date desc, cpl.cfr_part_desc asc) prior_end_date,
cpl.CFR_PART_DESC as cfr_part_desc,
cd.CFR_SUBPART as cfr_subpart
from table1 c
inner join table2 cd ON c.IND_ID = cd.IND_ID
AND cd.EFFECTIVE_DATE = c.EFFECTIVE_DATE
inner join table3 cpl on cd.CFR_PART_L_S = cpl.CFR_PART_L_S
inner join table4 f on c.ind_id = f.ind_id
inner join table5 p on f.ind_id = p.ind_id
where p.PERMIT_S = '4988'
order by c.effective_date desc, cpl.CFR_PART_DESC asc
);
Правка 2: Неверные данные были получены из-за неоднозначного определения даты вступления столбца в силу. Приведенный выше запрос теперь работает корректно.
Комментарии:
1. Зачем вам это вообще нужно? IMHO отображать данные в соответствии с вашими потребностями зависит от вашего клиента. Не делайте этого с SQL.
2. к сожалению, это должно быть сделано в соответствии с настройками системы. (Это устаревшая система). В значительной степени я создаю свой оператор sql, использую aspose и XML и отображаю выходные данные запроса в документе MS word.
Ответ №1:
Я думаю, вы ищете что-то подобное, используя аналитические функции. Мне не ясно, как упорядочен результирующий набор, поэтому вам придется заполнить это. Вы также, вероятно, сможете объединить аналитическую функцию в свой запрос вместо добавления третьего уровня вложенности.
SELECT (CASE WHEN effective_date = prior_effective_date
THEN null
ELSE effective_date
END) effective_date,
(CASE WHEN end_date = prior_end_date
THEN null
ELSE end_date
END) end_date,
description ,
subpart
FROM
(SELECT effective_date,
lag(effective_date) over
(order by effective_date desc, description asc) prior_effective_date,
end_date,
lag(end_date) over
(order by effective_date desc, description asc) prior_end_date,
desc,
subpart
FROM <<your query>>)
Комментарии:
1. У меня это так близко к работе. Я сортирую по effective_date по убыванию. Не могли бы вы обновить свой ответ моей сортировкой? Возможно, я что-то упускаю
2. @contactmatt — Откуда вы знаете, что «Обработка молочных продуктов» стоит перед «360 CMR 10.000», если оба
effective_date
значения одинаковы? Или есть разница с временным компонентом?3. Клиент, с которым мы работаем, ничего не указал, но я думаю, что имело бы смысл отсортировать по возрастанию описания. (Нет компонента времени)
4. @contactmatt — ОК. Обновлен ПОРЯДОК ПО в аналитических функциях
5. @Джастин Кейв, спасибо! Я обновил свой вопрос, включив мой запрос, объединенный с вашим шаблоном, и скриншот возвращенного набора данных. Это просто немного не так, и я не знаю, что это такое. Я думаю, что это может быть что-то с сортировкой.
Ответ №2:
Если вы используете SQL * Plus для генерации выходных данных, вы можете использовать BREAK
:
BREAK ON EFFECTIVE_DATE ON END_DATE
SELECT ...