Объединение двух периодических регистров (запрос или алгоритм)
Есть два периодических регистра (у обоих период день), назовем первый РегистрКоличество, второй - РегистрСостояние. Первый хранит количества на определенные даты, второй - состояния на определенные даты. Даты двух регистров независимы друг от друга. Требуется запросом построить третий регистр, являющийся объединением первых двух. То есть в третьем регистре будет три колонки "Дата", "Количество", "Состояние". В этом регистре не должно быть дублей дат и пустых, незаполненных полей, если их нет в исходных регистрах.
Наглядно:
Наглядно:
Прикрепленные файлы:

По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
мало, ну да ладно. не копейкой единой сыт человек.
держи
держи
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 4, 1) КАК Дата,
| 3 КАК Количество
|ПОМЕСТИТЬ ТаблицаКоличества
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 5, 6),
| 4
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 5, 18),
| 7
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 5, 30),
| 5
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 4, 1) КАК Дата,
| ""Отключено"" КАК Состояние
|ПОМЕСТИТЬ ТаблицаСостояний
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 5, 2),
| ""Включено""
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 5, 8),
| ""Приостановлено""
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2014, 5, 18),
| ""Включено""
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ЕСТЬNULL(ТаблицаКоличества.Дата, ТаблицаСостояний.Дата) КАК Дата,
| ТаблицаКоличества.Количество КАК Количество,
| ТаблицаСостояний.Состояние КАК Состояние
|ПОМЕСТИТЬ ТаблицаОбщая
|ИЗ
| ТаблицаКоличества КАК ТаблицаКоличества
| ПОЛНОЕ СОЕДИНЕНИЕ ТаблицаСостояний КАК ТаблицаСостояний
| ПО ТаблицаКоличества.Дата = ТаблицаСостояний.Дата
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТаблицаОбщая.Дата КАК Дата,
| ТаблицаОбщая.Количество КАК Количество,
| ТаблицаОбщая.Состояние КАК Состояние,
| МАКСИМУМ(ТаблицаОбщаяДляКоличества.Дата) КАК ДатаКоличества,
| МАКСИМУМ(ТаблицаОбщаяДляСостояния.Дата) КАК ДатаСостояния
|ПОМЕСТИТЬ ТаблицаДат
|ИЗ
| ТаблицаОбщая КАК ТаблицаОбщая
| ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаОбщая КАК ТаблицаОбщаяДляКоличества
| ПО (НЕ ТаблицаОбщаяДляКоличества.Количество ЕСТЬ NULL )
| И ТаблицаОбщая.Дата >= ТаблицаОбщаяДляКоличества.Дата
| ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаОбщая КАК ТаблицаОбщаяДляСостояния
| ПО (НЕ ТаблицаОбщаяДляСостояния.Состояние ЕСТЬ NULL )
| И ТаблицаОбщая.Дата >= ТаблицаОбщаяДляСостояния.Дата
|
|СГРУППИРОВАТЬ ПО
| ТаблицаОбщая.Дата,
| ТаблицаОбщая.Количество,
| ТаблицаОбщая.Состояние
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТаблицаДат.Дата КАК Дата,
| ЕстьNULL(ТаблицаДат.Количество, ТаблицаДатДляКоличества.Количество) КАК Количество,
| ЕстьNULL(ТаблицаДат.Состояние, ТаблицаДатДляСостояния.Состояние) КАК Состояние
|ИЗ
| ТаблицаДат КАК ТаблицаДат
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаДат КАК ТаблицаДатДляКоличества
| ПО ТаблицаДат.ДатаКоличества = ТаблицаДатДляКоличества.Дата
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаДат КАК ТаблицаДатДляСостояния
| ПО ТаблицаДат.ДатаСостояния = ТаблицаДатДляСостояния.Дата";
РезультатЗапроса = Запрос.Выполнить();
Показать
Вот еще один вариант. Он покороче в записи за счет использования коррелированных запросов. Начало такое же как в (5)
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 4, 1) КАК Дата,
3 КАК Количество
ПОМЕСТИТЬ ТаблицаКоличества
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 5, 6),
4
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 5, 18),
7
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 5, 30),
5
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 4, 1) КАК Дата,
"Отключено" КАК Состояние
ПОМЕСТИТЬ ТаблицаСостояний
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 5, 2),
"Включено"
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 5, 8),
"Приостановлено"
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 5, 18),
"Включено"
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВЫБОР
КОГДА ТаблицаКоличества.Дата > ТаблицаСостояний.Дата
ТОГДА ТаблицаКоличества.Дата
ИНАЧЕ ТаблицаСостояний.Дата
КОНЕЦ КАК Дата,
ТаблицаКоличества.Количество КАК Количество,
ТаблицаСостояний.Состояние КАК Состояние
ИЗ
ТаблицаКоличества КАК ТаблицаКоличества
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаСостояний КАК ТаблицаСостояний
ПО (ТаблицаСостояний.Дата В
(ВЫБРАТЬ
МАКСИМУМ(ТаблицаСостояний.Дата)
ИЗ
ТаблицаСостояний КАК ТаблицаСостояний
ГДЕ
ТаблицаСостояний.Дата <= ТаблицаКоличества.Дата)
ИЛИ ТаблицаКоличества.Дата В
(ВЫБРАТЬ
МАКСИМУМ(ТаблицаКоличества.Дата)
ИЗ
ТаблицаКоличества КАК ТаблицаКоличества
ГДЕ
ТаблицаКоличества.Дата <= ТаблицаСостояний.Дата))
Показать
У меня несколько вопросов к решениям (5) и (9): если в регистрах будут другие значения (даты и ресурсы), то запросы переписывать придется? А если в каждом регистре будет по 10 тыс. записей, то какой длины запрос будет ?
Я вообще не увидел обращения к регистрам, Вы берете конкретные значения...
Я вообще не увидел обращения к регистрам, Вы берете конкретные значения...
(12) DmitriiKopasov, начало запросов не относится к решению. Это просто способ сгенерировать тестовые таблицы, чтобы не нужно было создавать под эту задачу конфигурацию и заполнять регистры данными. Это обычная и часто применяемая практика. Понятно, что при привязке решения к конкретной конфигурации первые два запроса выбрасываются, а названия таблиц заменяются на названия объединяемых регистров сведений, имеющихся в конфигурации.
ВЫБРАТЬ
Колич.Период КАК Даты
ПОМЕСТИТЬ ВТ_Периоды
ИЗ
РегистрСведений.Колич КАК Колич
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
СостояниеТаб.Период
ИЗ
РегистрСведений.Состояние КАК СостояниеТаб
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Периоды.Даты
ПОМЕСТИТЬ ВТ_УпорядоченныеПериоды
ИЗ
ВТ_Периоды КАК ВТ_Периоды
СГРУППИРОВАТЬ ПО
ВТ_Периоды.Даты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_УпорядоченныеПериоды.Даты КАК Даты,
Колич.Количество,
СостояниеТаб.Состояние
ПОМЕСТИТЬ ВТ_ПустыеПоля
ИЗ
ВТ_УпорядоченныеПериоды КАК ВТ_УпорядоченныеПериоды
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Колич КАК Колич
ПО ВТ_УпорядоченныеПериоды.Даты = Колич.Период
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Состояние КАК СостояниеТаб
ПО ВТ_УпорядоченныеПериоды.Даты = СостояниеТаб.Период
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ПустыеПоля.Даты,
ВТ_ПустыеПоля.Количество,
ВТ_ПустыеПоля.Состояние,
МАКСИМУМ(Колич.Период) КАК ПериодКоличества
ПОМЕСТИТЬ ВТ_ДляПодсчетаКоличества
ИЗ
ВТ_ПустыеПоля КАК ВТ_ПустыеПоля
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Колич КАК Колич
ПО ВТ_ПустыеПоля.Даты >= Колич.Период
СГРУППИРОВАТЬ ПО
ВТ_ПустыеПоля.Даты,
ВТ_ПустыеПоля.Состояние,
ВТ_ПустыеПоля.Количество
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ДляПодсчетаКоличества.Даты КАК Даты,
ВТ_ДляПодсчетаКоличества.Состояние,
ВЫБОР
КОГДА ВТ_ДляПодсчетаКоличества.Количество ЕСТЬ NULL
ТОГДА Колич.Количество
ИНАЧЕ ВТ_ДляПодсчетаКоличества.Количество
КОНЕЦ КАК Количество
ПОМЕСТИТЬ ВТ_Количества
ИЗ
ВТ_ДляПодсчетаКоличества КАК ВТ_ДляПодсчетаКоличества
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Колич КАК Колич
ПО ВТ_ДляПодсчетаКоличества.ПериодКоличества = Колич.Период
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Количества.Даты,
ВТ_Количества.Состояние,
ВТ_Количества.Количество,
МАКСИМУМ(СостояниеТаб.Период) КАК ПериодСостояния
ПОМЕСТИТЬ ВТ_ДляСостояния
ИЗ
ВТ_Количества КАК ВТ_Количества
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Состояние КАК СостояниеТаб
ПО ВТ_Количества.Даты > СостояниеТаб.Период
СГРУППИРОВАТЬ ПО
ВТ_Количества.Даты,
ВТ_Количества.Состояние,
ВТ_Количества.Количество
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ДляСостояния.Даты КАК Даты,
ВТ_ДляСостояния.Количество,
ВЫБОР
КОГДА ВТ_ДляСостояния.Состояние ЕСТЬ NULL
ТОГДА СостояниеТаб.Состояние
ИНАЧЕ ВТ_ДляСостояния.Состояние
КОНЕЦ КАК Состояние
ИЗ
ВТ_ДляСостояния КАК ВТ_ДляСостояния
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Состояние КАК СостояниеТаб
ПО ВТ_ДляСостояния.ПериодСостояния = СостояниеТаб.Период
УПОРЯДОЧИТЬ ПО
Даты
Показать
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот