Транспонирование в запросе

1. Win98 16.01.13 13:03 Сейчас в теме
Уже делал и не раз, но как уже и не помню. Наверное, надо записать пример и где-нибудь сохранить :)
Итак, имеем:
К1,П1
К1,П2
К1, П3
К2, П1
К2, П2

Кх,П3
Надо получить
К1,П1,П2,П3
К2,П1,П2,П3

Кх,П1,П2,П3

Второй вариант
К1,П1,пусто,пусто
К1,пусто,П2,пусто
К1, пусто,пусто,П3
К2, П1,пусто,пусто
К2, пусто,П2,пусто

Кх,пусто,пусто,П3
Надо получить
К1,П1,П2,П3
К2,П1,П2,П3

Кх,П1,П2,П3

Поделитесь примерами запросов.
Спасибо.
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
5. stanru1 91 17.01.13 12:52 Сейчас в теме
(1) как делать "непрямыми" методами на 1С писать не буду, ибо это и так известно с небольшими вариациями на тему.

Для MSSQL достаточно будет сделать так:

create table #t(
	id int,
	sm float
)

insert into #t
select 1,1212121

insert into #t
select 2,444

insert into #t
select 3,5656



select * from #t
pivot(
	sum(sm)
	for id in ([1],[2],[3])
) as pvt

Показать
результат:

1 2 3
1212121 444 5656
6. AnderWonder 27 17.01.13 13:17 Сейчас в теме
(1) В первом случае если количество П фиксировано, например не больше 3, как в примере, то можно сделать три левых соединения. Первым запросом выбрать и сгруппировать К, ну а потом цеплять левым соединением выборки по каждому полю.
7. Win98 17.01.13 17:01 Сейчас в теме
(6) AnderWonder, совершенно верно, так и сделал. В реальности 4 вариации. Делаю полное соединение.
Но вылез баг, делаю на СКД, если в одном запросе делать более одного соединения то происходит что-то странное - часть данных теряется, хотя соединение и полное. Приходится каждое соединения оформлять в виде временной таблицы.
9. Hany 17.01.13 17:34 Сейчас в теме
(7) Win98, по тем полям, которые пропадают, ставьте флаг "Обязательное"..Может поможет.
Прикрепленные файлы:
10. AnderWonder 27 17.01.13 17:39 Сейчас в теме
(7) Скорее всего не баг, а ошибка в запросе.
11. Win98 18.01.13 10:24 Сейчас в теме
(10) AnderWonder, где там ошибаться? Там всего две строчки. Сейчас эксперименты ставлю - пытаюсь понять что происходит. Если раскопаю - сообщу.
12. AnderWonder 27 18.01.13 10:36 Сейчас в теме
(11) Ошибиться можно и в половине строчке. Лучше бы текст запроса привели.
13. Win98 18.01.13 11:09 Сейчас в теме
(12) AnderWonder, можно
ВЫБРАТЬ
ВТ_ДИА.Ссылка,
ВТ_ДИА.Наименование,
ВТ_ДИА.Аварийная,
ВТ_ДИА.РайонГорода,
ВТ_КАварийные.КАварийная,
ВТ_Исполнитель.Исполнитель 
ИЗ
ВТ_ДИА КАК ВТ_ДИА
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_КАварийные КАК ВТ_КАварийные
ПО ВТ_ДИА.Ссылка = ВТ_КАварийные.Дом
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Исполнитель КАК ВТ_Исполнитель
ПО ВТ_ДИА.Ссылка = ВТ_Исполнитель.Дом
Показать
14. AnderWonder 27 18.01.13 13:07 Сейчас в теме
(7)(13)
если одном запросе делать более одного соединения то происходит что-то странное - часть данных теряется, хотя соединение и полное

короче консоль запросов вам в помощь.
2. -FeNiX- 16.01.13 13:11 Сейчас в теме
В первом случае, достаточно групировки по полю К1, К2
3. Win98 16.01.13 14:02 Сейчас в теме
(2) -FeNiX-, как это? Сгруппировал я по полю К, а что получилось в поле П?

Фигня получается в поле П.
Вообще-то должно получится ПолеК, ПолеП1, ПолеП2, ПолеП3

Можно поподробнее как надо сгруппировать, я наверное что-то не понял?
Спасибо.
4. juntatalor 63 17.01.13 12:13 Сейчас в теме
Прямых способов решения для первого варианта нет. Самое простое - заполнить таблицу программным кодом, затем поместить ее как временную в запрос. Не мучайтесь, пытаясь сделать это в запросе - получится либо крайне ненаглядный текст запроса, либо динамическое формирование текста запроса, либо еще какие-то неприятности, а работать быстрее в итоге не станет.

Для второго случая, как правильно говорят, надо использовать группировку:

ВЫБРАТЬ
К КАК К,
МАКСИМУМ(П1) КАК П1,
МАКСИМУМ(П2) КАК П2,
...,
МАКСИМУМ(ПN) КАК ПN
ИЗ ...
СГРУППИРОВАТЬ ПО К
8. Win98 17.01.13 17:05 Сейчас в теме
(4) juntatalor, делаю так же как и в первом случае - через соединение. Т.е. в первую временную таблицу выбираю К и П1, во вторую К и П2 и т.д. Потом соединяю таблицы по К.
15. Hany 18.01.13 16:24 Сейчас в теме
У меня есть интересное решение, скорее извращение, но зато изысканное:)
С помощью СКД мы можем выполнить желаемое транспонирование, ведь так?
После этого все бы хорошо и можно было запросто выгрузить в ТЗ процессором вывода в коллекцию значений (взяв решение отсюда http://infostart.ru/public/124685/), но у нас в структуре будет таблица, т.к. изначально количество колонок неизвестно и выгрузить так просто не получится.

Код в обработчике на кнопке на форме отчета:
Выгружаем все табличный документ:

ТабДок = Новый ТабличныйДокумент;
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки);
	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , , Истина);	
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ТабДок);
	ПроцессорВывода.НачатьВывод();
	Пока Истина Цикл
		ОбработкаПрерыванияПользователя();
		ЭлементРезультата = ПроцессорКомпоновки.Следующий();
		Если ЭлементРезультата = Неопределено Тогда
			Прервать;
		Иначе
			ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
		КонецЕсли;	
	КонецЦикла;		
	ПроцессорВывода.ЗакончитьВывод();
Показать


Затем сохраняем во временный файл (потом удалим):

	ТекФайл = Строка(Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy"));
	ТабДок.Записать(КаталогВременныхФайлов() + ТекФайл, ТипФайлаТабличногоДокумента.XLS);



Затем читаем путем универсальной функции (подобная есть у любого в каком-то супер пупер общем модуле):

        ТЗ = СформироватьТЗсEXCEL(КаталогВременныхФайлов() + ТекФайл, 3, , 1, );



Затем заполняем ТЗ, если нужно на форме, и удаляем временный файл:


	
        ЭлементыФормы.ТабПоле.Значение = ТЗ;
	ЭлементыФормы.ТабПоле.СоздатьКолонки();
	УдалитьФайлы(КаталогВременныхФайлов() + ТекФайл, "");


На всяк случай тестовый отчет вложила, на нем я тренировалась:)
Прикрепленные файлы:
Тест1.erf
17. AnderWonder 27 18.01.13 17:29 Сейчас в теме
(15) удаление гланд через задний проход. Если уж не одним запросом, то проще цикл написать.
18. Hany 18.01.13 17:42 Сейчас в теме
(17) AnderWonder, зато универсально.
А запрос в цикле опишет только один запрос и никакой больше, и параметры на лету с отбором изменить в предприятии нельзя. Да и про запросы в цикле дурная слава ходит:)

А в СКД настроил на лету любые группировки, любые отборы и в моем коде выгрузки в ТЗ править ничего не надо.

Добавлено: а кто сказал, что все программирование в 1С - не есть удаление гланд через это место?:)))))))
19. AnderWonder 27 18.01.13 17:56 Сейчас в теме
(18) Универсально для чего? Если запрос в обработке, модуле документа, общем модуле и т.п.?
Функцию транспонирования таблицы значений можно в общем модуле написать - будет универсально.
Кому как, конечно, но, как по мне, вполне можно на 1С приличный код писать. А то, что в связи с доступностью, недоучек развелось тьма-тьмущая (себя, между прочим, тоже к ним причисляю) - это совсем другая история.
20. Hany 18.01.13 18:08 Сейчас в теме
(19) AnderWonder,
Функцию транспонирования таблицы значений можно в общем модуле написать


про запросы в цикле проигнорировали...

как по мне, вполне можно на 1С приличный код писать.


Конечно, можно!
Но 1С такая штука, что не все позволяет писать приличным кодом...приходится неприличным извращаться:)
21. juntatalor 63 19.01.13 04:08 Сейчас в теме
(20) Hany, все она позволяет нормальным кодом писать.
Как правило, самый жесткие проблемы возникают при неправильной постановке задачи, а неправильная постановка задачи - из-за незнания особенностей языка 1С.

Например: О! Вот если мы транспонируем таблицу, то получится это выполнить быстро и прямо на лету в запросе. Опа, транспонировать быстро и удобно нельзя, дурная 1С.

Как надо: Так, нам надо сделать это средствами 1С. У нас есть такой, такой, такой механизмы, с помощью какого делаем?
22. Hany 21.01.13 12:00 Сейчас в теме
(21) juntatalor, и какой вывод? где ответ на последний вопрос?:)

с помощью какого делаем?


:)
16. MineevaNT 18.01.13 16:33 Сейчас в теме
Логично использовать объединение запросов.

Выбрать
К1,
П1 как П1,
0 как П2,
0 как П3
из
Выбрать
К1, п1,
К1, п2,
............
Объединить

Выбрать
К1,
0,
П2,
0
из
Выбрать
К1, п1,
К1, п2,
............
23. Obertone 74 30.09.22 10:01 Сейчас в теме
Транспонирование строк в столбцы в запросе удобно целиком делать согласно этой статье (https://infostart.ru/1c/articles/1342853/)
таким образом (на примере дополнительных сведений):

ВЫБРАТЬ
	ДополнительныеСведения.Объект КАК Объект,
	ДополнительныеСведения.Свойство КАК Свойство,
	ДополнительныеСведения.Значение КАК Значение	
	ПОМЕСТИТЬ ДополнительныеСведения_
ИЗ
	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
ГДЕ
	ТИПЗНАЧЕНИЯ(ДополнительныеСведения.Объект) = ТИП(...);

ВЫБРАТЬ
	ДополнительныеСведения_.Объект КАК Объект,
	
	МАКСИМУМ(
			ВЫБОР
				КОГДА ДополнительныеСведения_.Свойство.Имя = "ИмяСвойства1"
					ТОГДА ДополнительныеСведения_.Значение
				ИНАЧЕ NULL
			КОНЕЦ
		) КАК Свойство1,

	МАКСИМУМ(
			ВЫБОР
				КОГДА ДополнительныеСведения_.Свойство.Имя = "ИмяСвойства2"
					ТОГДА ДополнительныеСведения_.Значение
				ИНАЧЕ NULL
			КОНЕЦ
		) КАК Свойство2,

	...		

ИЗ	ДополнительныеСведения_ КАК ДополнительныеСведения_
ГДЕ	
	ДополнительныеСведения_.Свойство В
	( 
ВЫБРАТЬ
	ДополнительныеРеквизитыИСведения.Ссылка КАК Ссылка
ИЗ
	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
ГДЕ
	ДополнительныеРеквизитыИСведения.Имя = "ИмяСвойства1" ИЛИ
ДополнительныеРеквизитыИСведения.Имя = "ИмяСвойства2" ИЛИ ...

	)

СГРУППИРОВАТЬ ПО
	ДополнительныеСведения_.Объект
Показать
Оставьте свое сообщение

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