Объединение двух периодических регистров (запрос или алгоритм)

1. dmprokopyev 26.05.14 19:34 Сейчас в теме
Есть два периодических регистра (у обоих период день), назовем первый РегистрКоличество, второй - РегистрСостояние. Первый хранит количества на определенные даты, второй - состояния на определенные даты. Даты двух регистров независимы друг от друга. Требуется запросом построить третий регистр, являющийся объединением первых двух. То есть в третьем регистре будет три колонки "Дата", "Количество", "Состояние". В этом регистре не должно быть дублей дат и пустых, незаполненных полей, если их нет в исходных регистрах.
Наглядно:
Прикрепленные файлы:
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. spezc 782 26.05.14 19:43 Сейчас в теме
А вопрос, простите, в чем?
3. dmprokopyev 26.05.14 19:48 Сейчас в теме
Вопрос: как это сделать запросом?
4. dmprokopyev 26.05.14 20:06 Сейчас в теме
5. spezc 782 26.05.14 21:19 Сейчас в теме
мало, ну да ладно. не копейкой единой сыт человек.
держи

Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
|	ДАТАВРЕМЯ(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(ТаблицаДат.Состояние, ТаблицаДатДляСостояния.Состояние) КАК Состояние
|ИЗ
|	ТаблицаДат КАК ТаблицаДат
|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаДат КАК ТаблицаДатДляКоличества
|		ПО ТаблицаДат.ДатаКоличества = ТаблицаДатДляКоличества.Дата
|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаДат КАК ТаблицаДатДляСостояния
|		ПО ТаблицаДат.ДатаСостояния = ТаблицаДатДляСостояния.Дата";
РезультатЗапроса = Запрос.Выполнить();
Показать
9. ildarovich 7865 27.05.14 11:07 Сейчас в теме
Вот еще один вариант. Он покороче в записи за счет использования коррелированных запросов. Начало такое же как в (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),
	"Включено"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВЫБОР
		КОГДА ТаблицаКоличества.Дата > ТаблицаСостояний.Дата
			ТОГДА ТаблицаКоличества.Дата
		ИНАЧЕ ТаблицаСостояний.Дата
	КОНЕЦ КАК Дата,
	ТаблицаКоличества.Количество КАК Количество,
	ТаблицаСостояний.Состояние КАК Состояние
ИЗ
	ТаблицаКоличества КАК ТаблицаКоличества
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаСостояний КАК ТаблицаСостояний
		ПО (ТаблицаСостояний.Дата В
					(ВЫБРАТЬ
						МАКСИМУМ(ТаблицаСостояний.Дата)
					ИЗ
						ТаблицаСостояний КАК ТаблицаСостояний
					ГДЕ
						ТаблицаСостояний.Дата <= ТаблицаКоличества.Дата)
				ИЛИ ТаблицаКоличества.Дата В
					(ВЫБРАТЬ
						МАКСИМУМ(ТаблицаКоличества.Дата)
					ИЗ
						ТаблицаКоличества КАК ТаблицаКоличества
					ГДЕ
						ТаблицаКоличества.Дата <= ТаблицаСостояний.Дата))
Показать
spezc; AllexSoft; +2 Ответить
10. spezc 782 27.05.14 12:26 Сейчас в теме
(9) ildarovich, зачет, одобряю)
12. DmitriiKopasov 13 27.05.14 12:55 Сейчас в теме
У меня несколько вопросов к решениям (5) и (9): если в регистрах будут другие значения (даты и ресурсы), то запросы переписывать придется? А если в каждом регистре будет по 10 тыс. записей, то какой длины запрос будет ?
Я вообще не увидел обращения к регистрам, Вы берете конкретные значения...
13. spezc 782 27.05.14 14:50 Сейчас в теме
15. ildarovich 7865 27.05.14 22:46 Сейчас в теме
(12) DmitriiKopasov, начало запросов не относится к решению. Это просто способ сгенерировать тестовые таблицы, чтобы не нужно было создавать под эту задачу конфигурацию и заполнять регистры данными. Это обычная и часто применяемая практика. Понятно, что при привязке решения к конкретной конфигурации первые два запроса выбрасываются, а названия таблиц заменяются на названия объединяемых регистров сведений, имеющихся в конфигурации.
16. DmitriiKopasov 13 27.05.14 23:27 Сейчас в теме
(15) Да, я понял уже. Увидел начало запроса и немного офигел, потом только дочитал запрос до конца и разобрался...
6. DmitriiKopasov 13 26.05.14 23:02 Сейчас в теме
ВЫБРАТЬ
	Колич.Период КАК Даты
ПОМЕСТИТЬ ВТ_Периоды
ИЗ
	РегистрСведений.Колич КАК Колич

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	СостояниеТаб.Период
ИЗ
	РегистрСведений.Состояние КАК СостояниеТаб
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Периоды.Даты
ПОМЕСТИТЬ ВТ_УпорядоченныеПериоды
ИЗ
	ВТ_Периоды КАК ВТ_Периоды

СГРУППИРОВАТЬ ПО
	ВТ_Периоды.Даты
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_УпорядоченныеПериоды.Даты КАК Даты,
	Колич.Количество,
	СостояниеТаб.Состояние
ПОМЕСТИТЬ ВТ_ПустыеПоля
ИЗ
	ВТ_УпорядоченныеПериоды КАК ВТ_УпорядоченныеПериоды
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Колич КАК Колич
		ПО ВТ_УпорядоченныеПериоды.Даты = Колич.Период
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Состояние КАК СостояниеТаб
		ПО ВТ_УпорядоченныеПериоды.Даты = СостояниеТаб.Период
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_ПустыеПоля.Даты,
	ВТ_ПустыеПоля.Количество,
	ВТ_ПустыеПоля.Состояние,
	МАКСИМУМ(Колич.Период) КАК ПериодКоличества
ПОМЕСТИТЬ ВТ_ДляПодсчетаКоличества
ИЗ
	ВТ_ПустыеПоля КАК ВТ_ПустыеПоля
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Колич КАК Колич
		ПО ВТ_ПустыеПоля.Даты >= Колич.Период

СГРУППИРОВАТЬ ПО
	ВТ_ПустыеПоля.Даты,
	ВТ_ПустыеПоля.Состояние,
	ВТ_ПустыеПоля.Количество
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_ДляПодсчетаКоличества.Даты КАК Даты,
	ВТ_ДляПодсчетаКоличества.Состояние,
	ВЫБОР
		КОГДА ВТ_ДляПодсчетаКоличества.Количество ЕСТЬ NULL 
			ТОГДА Колич.Количество
		ИНАЧЕ ВТ_ДляПодсчетаКоличества.Количество
	КОНЕЦ КАК Количество
ПОМЕСТИТЬ ВТ_Количества
ИЗ
	ВТ_ДляПодсчетаКоличества КАК ВТ_ДляПодсчетаКоличества
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Колич КАК Колич
		ПО ВТ_ДляПодсчетаКоличества.ПериодКоличества = Колич.Период
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Количества.Даты,
	ВТ_Количества.Состояние,
	ВТ_Количества.Количество,
	МАКСИМУМ(СостояниеТаб.Период) КАК ПериодСостояния
ПОМЕСТИТЬ ВТ_ДляСостояния
ИЗ
	ВТ_Количества КАК ВТ_Количества
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Состояние КАК СостояниеТаб
		ПО ВТ_Количества.Даты > СостояниеТаб.Период

СГРУППИРОВАТЬ ПО
	ВТ_Количества.Даты,
	ВТ_Количества.Состояние,
	ВТ_Количества.Количество
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_ДляСостояния.Даты КАК Даты,
	ВТ_ДляСостояния.Количество,
	ВЫБОР
		КОГДА ВТ_ДляСостояния.Состояние ЕСТЬ NULL 
			ТОГДА СостояниеТаб.Состояние
		ИНАЧЕ ВТ_ДляСостояния.Состояние
	КОНЕЦ КАК Состояние
ИЗ
	ВТ_ДляСостояния КАК ВТ_ДляСостояния
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Состояние КАК СостояниеТаб
		ПО ВТ_ДляСостояния.ПериодСостояния = СостояниеТаб.Период

УПОРЯДОЧИТЬ ПО
	Даты
Показать
Pioner777; adva; +2 Ответить
7. spezc 782 26.05.14 23:28 Сейчас в теме
(6) Мда... Ничего лично, но не дай бог мне разбираться в твоем коде
8. DmitriiKopasov 13 27.05.14 08:03 Сейчас в теме
Запрос получился не оптимальным, хотя ничего сложного в нем нет. А главное - работает.
11. spezc 782 27.05.14 12:27 Сейчас в теме
а автор видать на радостях даже спасибо забыл сказать
14. dmprokopyev 27.05.14 17:59 Сейчас в теме
Всем большое спасибо, просмотреть смогу к сожалению только завтра, прошу за это прощения.
17. DexterMorgan777 3 18.02.15 22:35 Сейчас в теме
Подскажите как быть если в этих регистрах еще есть ссылки на объект? Т.е. Нам надо не все по дате сводить, а только те у которых равны эти ссылки.

Например у регистра 1 есть дата, ссылка на элемент справочника и количество. Во втором регистре дата, ссылка на элемент справочника и состояние?
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот