Уже делал и не раз, но как уже и не помню. Наверное, надо записать пример и где-нибудь сохранить :)
Итак, имеем: К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
(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) В первом случае если количество П фиксировано, например не больше 3, как в примере, то можно сделать три левых соединения. Первым запросом выбрать и сгруппировать К, ну а потом цеплять левым соединением выборки по каждому полю.
(6) AnderWonder, совершенно верно, так и сделал. В реальности 4 вариации. Делаю полное соединение.
Но вылез баг, делаю на СКД, если в одном запросе делать более одного соединения то происходит что-то странное - часть данных теряется, хотя соединение и полное. Приходится каждое соединения оформлять в виде временной таблицы.
ВЫБРАТЬ
ВТ_ДИА.Ссылка,
ВТ_ДИА.Наименование,
ВТ_ДИА.Аварийная,
ВТ_ДИА.РайонГорода,
ВТ_КАварийные.КАварийная,
ВТ_Исполнитель.Исполнитель
ИЗ
ВТ_ДИА КАК ВТ_ДИА
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_КАварийные КАК ВТ_КАварийные
ПО ВТ_ДИА.Ссылка = ВТ_КАварийные.Дом
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Исполнитель КАК ВТ_Исполнитель
ПО ВТ_ДИА.Ссылка = ВТ_Исполнитель.Дом
Прямых способов решения для первого варианта нет. Самое простое - заполнить таблицу программным кодом, затем поместить ее как временную в запрос. Не мучайтесь, пытаясь сделать это в запросе - получится либо крайне ненаглядный текст запроса, либо динамическое формирование текста запроса, либо еще какие-то неприятности, а работать быстрее в итоге не станет.
Для второго случая, как правильно говорят, надо использовать группировку:
ВЫБРАТЬ
К КАК К,
МАКСИМУМ(П1) КАК П1,
МАКСИМУМ(П2) КАК П2,
...,
МАКСИМУМ(ПN) КАК ПN
ИЗ ...
СГРУППИРОВАТЬ ПО К
(4) juntatalor, делаю так же как и в первом случае - через соединение. Т.е. в первую временную таблицу выбираю К и П1, во вторую К и П2 и т.д. Потом соединяю таблицы по К.
У меня есть интересное решение, скорее извращение, но зато изысканное:)
С помощью СКД мы можем выполнить желаемое транспонирование, ведь так?
После этого все бы хорошо и можно было запросто выгрузить в ТЗ процессором вывода в коллекцию значений (взяв решение отсюда http://infostart.ru/public/124685/), но у нас в структуре будет таблица, т.к. изначально количество колонок неизвестно и выгрузить так просто не получится.
Код в обработчике на кнопке на форме отчета:
Выгружаем все табличный документ:
ТабДок = Новый ТабличныйДокумент;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , , Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ОбработкаПрерыванияПользователя();
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
Иначе
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЕсли;
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
(17) AnderWonder, зато универсально.
А запрос в цикле опишет только один запрос и никакой больше, и параметры на лету с отбором изменить в предприятии нельзя. Да и про запросы в цикле дурная слава ходит:)
А в СКД настроил на лету любые группировки, любые отборы и в моем коде выгрузки в ТЗ править ничего не надо.
Добавлено: а кто сказал, что все программирование в 1С - не есть удаление гланд через это место?:)))))))
(18) Универсально для чего? Если запрос в обработке, модуле документа, общем модуле и т.п.?
Функцию транспонирования таблицы значений можно в общем модуле написать - будет универсально.
Кому как, конечно, но, как по мне, вполне можно на 1С приличный код писать. А то, что в связи с доступностью, недоучек развелось тьма-тьмущая (себя, между прочим, тоже к ним причисляю) - это совсем другая история.
(20) Hany, все она позволяет нормальным кодом писать.
Как правило, самый жесткие проблемы возникают при неправильной постановке задачи, а неправильная постановка задачи - из-за незнания особенностей языка 1С.
Например: О! Вот если мы транспонируем таблицу, то получится это выполнить быстро и прямо на лету в запросе. Опа, транспонировать быстро и удобно нельзя, дурная 1С.
Как надо: Так, нам надо сделать это средствами 1С. У нас есть такой, такой, такой механизмы, с помощью какого делаем?
Транспонирование строк в столбцы в запросе удобно целиком делать согласно этой статье (https://infostart.ru/1c/articles/1342853/) таким образом (на примере дополнительных сведений):
ВЫБРАТЬ
ДополнительныеСведения.Объект КАК Объект,
ДополнительныеСведения.Свойство КАК Свойство,
ДополнительныеСведения.Значение КАК Значение
ПОМЕСТИТЬ ДополнительныеСведения_
ИЗ
РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
ГДЕ
ТИПЗНАЧЕНИЯ(ДополнительныеСведения.Объект) = ТИП(...);
ВЫБРАТЬ
ДополнительныеСведения_.Объект КАК Объект,
МАКСИМУМ(
ВЫБОР
КОГДА ДополнительныеСведения_.Свойство.Имя = "ИмяСвойства1"
ТОГДА ДополнительныеСведения_.Значение
ИНАЧЕ NULL
КОНЕЦ
) КАК Свойство1,
МАКСИМУМ(
ВЫБОР
КОГДА ДополнительныеСведения_.Свойство.Имя = "ИмяСвойства2"
ТОГДА ДополнительныеСведения_.Значение
ИНАЧЕ NULL
КОНЕЦ
) КАК Свойство2,
...
ИЗ ДополнительныеСведения_ КАК ДополнительныеСведения_
ГДЕ
ДополнительныеСведения_.Свойство В
(
ВЫБРАТЬ
ДополнительныеРеквизитыИСведения.Ссылка КАК Ссылка
ИЗ
ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
ГДЕ
ДополнительныеРеквизитыИСведения.Имя = "ИмяСвойства1" ИЛИ
ДополнительныеРеквизитыИСведения.Имя = "ИмяСвойства2" ИЛИ ...
)
СГРУППИРОВАТЬ ПО
ДополнительныеСведения_.Объект