Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Перекрестный запрос (число прочтений - 3663 )
Anna
Junior Member
**
Отсутствует


1C++

Сообщений: 39
Зарегистрирован: 02. Декабря 2009
Пол: Женский
Перекрестный запрос
23. Июня 2010 :: 10:18
Печать  
Добрый день. Возник вопрос такого плана,что такое перекрестный запрос. Нужно для составления итоговой таблички такого плана
                        
                                1 июня           2 июня       3 июня ......
Товра1Продано         1 шт                 -                -
Товра2Продано            -                5 шт              -
Товра3Продано         10 шт               -                -

Периодичность м.б. дни, неделя, месяц, квартал, год. Кто сталкивался?
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перекрестный запрос
Ответ #1 - 23. Июня 2010 :: 10:35
Печать  
Что-то такое, как на картинке?
  

3_001.PNG ( 43 KB | Загрузки )
3_001.PNG

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Anna
Junior Member
**
Отсутствует


1C++

Сообщений: 39
Зарегистрирован: 02. Декабря 2009
Пол: Женский
Re: Перекрестный запрос
Ответ #2 - 23. Июня 2010 :: 10:40
Печать  
Да
  
Наверх
 
IP записан
 
Anna
Junior Member
**
Отсутствует


1C++

Сообщений: 39
Зарегистрирован: 02. Декабря 2009
Пол: Женский
Re: Перекрестный запрос
Ответ #3 - 23. Июня 2010 :: 10:44
Печать  
Собственно есть такой запрос....но вот подходит ли он для решения поставленной  задачи...

Если ПериодичностьСтр = "День" Тогда
     СтрокаПериодв1 = "datePART(dd,LEFT(Жур.Date_Time_IDDoc, 8))Период ,";
     СтрокаГруппировкиSQL3 = ",datePART(      dd,LEFT(Жур.Date_Time_IDDoc,8))";
ИначеЕсли ПериодичностьСтр = "Неделя" Тогда
     СтрокаПериодв1 = "datePART(      wk,LEFT(Жур.Date_Time_IDDoc,8)) Период,";
     СтрокаГруппировкиSQL3 = ",datePART(      wk,LEFT(Жур.Date_Time_IDDoc,8))";
ИначеЕсли ПериодичностьСтр = "Месяц" Тогда
     СтрокаПериодв1 = "datePART(      mm,LEFT(Жур.Date_Time_IDDoc,8))  Период,";
     СтрокаГруппировкиSQL3 = ",datePART(      mm,LEFT(Жур.Date_Time_IDDoc,8))";
ИначеЕсли ПериодичностьСтр = "Квартал" Тогда
     СтрокаПериодв1 = "datePART(      qq,LEFT(Жур.Date_Time_IDDoc,8))  Период,";
     СтрокаГруппировкиSQL3 = ",datePART(      qq,LEFT(Жур.Date_Time_IDDoc,8))";
ИначеЕсли ПериодичностьСтр = "Год" Тогда
     СтрокаПериодв1 = "datePART(yyyy,LEFT(Жур.Date_Time_IDDoc,8))  Период,";
     СтрокаГруппировкиSQL3 = ",datePART(yyyy,LEFT(Жур.Date_Time_IDDoc,8))";
КонецЕсли;



ТекстЗапроса = "

     |SELECT
     |      Жур.IDDOC as [Док $Документ],
     |      Жур.IDDocDef as Док_вид,
     |      CAST(LEFT(Жур.Date_Time_IDDoc, 8) as DateTime) as ДатаДок,
     |      $ДокС.Товар as [Товар $Справочник.Товары],
     |      $ДокС.Количество as Количество,
     |      $Док.Склад as [Склад $Справочник.Склады],
     |      Док.$ОбщийРеквизит.АвторПроведения as Сотрудник,
     |   Жур.$ОбщийРеквизит.Подразделение as [Подразделение $Справочник.Подразделение],
     |      $Док.ПричинаВозврата as [ПричинаВозврата $Перечисление.Причина_возврата],
     |      "+?(ПериодичностьСтр <> "Пусто" ,""+СтрокаПериодв1+"","")+"
     |      $Док.ПризнакНакладной as [ПризнакН $Перчисление.ПризнНакл]
     |FROM
     |    $ДокументСтроки.Приходная as ДокС
     |INNER JOIN
     |    $Документ.Приходная as Док ON Док.IDDoc = ДокС.IDDoc and
     |       $Док.ПризнакНакладной = '"+sql_pзнач_булево_Возврат+"'
     |      "+?(ВыбСотрудник.Выбран() =1 ,"and (Док.$ОбщийРеквизит.АвторПроведения =:Автор)","")+"
     |      "+?(ПричинаВозврата.Выбран() =1 ,"and ($ДокС.ПричинаВозврата =:Причина)","")+"
     |      "+?(ВыбСклад.GetListSize()>0,"and($Док.Склад IN (SELECT val FROM #v_selected_sklad))","")+"
     |      "+?(ВыбТовар.GetListSize()>0,"and($ДокС.Товар IN (SELECT val FROM #v_selected_tovar))","")+"
     |INNER JOIN
     |    _1SJourn as Жур ON Жур.IDDoc = ДокС.IDDoc AND
     |                       Жур.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~ AND
     |                       Жур.Closed & 1 = 1
     |                                    "+?(Подразделение.Выбран() =1 ,"and (Жур.$ОбщийРеквизит.Подразделение  =:Подразделение)","")+"
     |";

  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Перекрестный запрос
Ответ #4 - 23. Июня 2010 :: 11:24
Печать  
Не подходит, тебе нужна таблица с периодами. Типа такого:
Код
Выбрать все
Функция ЗаполнитьТаблицуДат(ИмяПериода)


	RS.Отладка(фОтладка);
	RS.Выполнить("drop table #tmp_dates");
	ТекстЗапроса = "
	|begin
	|create table #tmp_dates
	|     (
	|	 dateB datetime not null,
	|	 dateE datetime not null
	|     )
	|create unique index indx_dateb on #tmp_dates(dateB)
	|create unique index indx_datee on #tmp_dates(dateE)
	|end
	|";

	RS.Отладка(фОтладка);

	рез = RS.Выполнить(ТекстЗапроса);
	Если рез = 0 Тогда
		Сообщить(RS.ПолучитьОписаниеОшибки());
		Возврат 0;
	КонецЕсли;

	Если ИмяПериода = "" Тогда
		ТекстЗапроса = "
		|insert into #tmp_dates(dateB,dateE)
		|select
		|  cast('"+Формат(ДатаС,"ДГГГГММДД")+"' as datetime)  dateB,
		|  cast('"+Формат(ДатаПо,"ДГГГГММДД")+"' as datetime)  dateE
		|";

	Иначе

		ТекстЗапроса = "
		|declare @@dateB datetime
		|declare @@dateE datetime
		|
		|set @@dateB = cast('"+Формат(ДатаС,"ДГГГГММДД")+"' as datetime)
		|set @@dateE = cast('"+Формат(ДатаПо,"ДГГГГММДД")+"' as datetime)
		|";

		Если ИмяПериода = "День" Тогда

			ТекстЗапроса = ТекстЗапроса + "
			|while @@dateB<=@@dateE
			|begin
			|  insert into #tmp_dates
			|  select
			|     @@dateB   dateB,
			|     @@dateB   dateE
			|
			|  set @@dateB = dateadd(d,1,@@dateB)
			|end
			|";


		Иначе
			ИмяФункцииНачПериода = ИмяБД + ".dbo.";
			ИмяФункцииКонПериода = ИмяБД + ".dbo.";
		    стрDatePart	    = "";

			Если ИмяПериода = "Неделя"	Тогда
				ИмяФункцииНачПериода = ИмяФункцииНачПериода + "WeekBegin";
				ИмяФункцииКонПериода = ИмяФункцииКонПериода + "WeekEnd";
				стрDatePart	    = "wk";
			ИначеЕсли ИмяПериода = "Месяц" Тогда
				ИмяФункцииНачПериода = ИмяФункцииНачПериода + "MonthBegin";
				ИмяФункцииКонПериода = ИмяФункцииКонПериода + "MonthEnd";
				стрDatePart	    = "m";
			ИначеЕсли ИмяПериода = "Квартал" Тогда
				ИмяФункцииНачПериода = ИмяФункцииНачПериода + "QuarterBegin";
				ИмяФункцииКонПериода = ИмяФункцииКонПериода + "QuarterEnd";
				стрDatePart	    = "q";
			ИначеЕсли ИмяПериода = "Год" Тогда
				ИмяФункцииНачПериода = ИмяФункцииНачПериода + "YearBegin";
				ИмяФункцииКонПериода = ИмяФункцииКонПериода + "YearEnd";
				стрDatePart	    = "yy";
			КонецЕсли;

			ТекстЗапроса = ТекстЗапроса + "
			|set @@dateb = "+ИмяФункцииНачПериода+"(@@dateb)
			|
			|set datefirst 1
			|
			|while @@dateb <= @@datee
			|begin
			|    insert into #tmp_dates(dateb,datee)
			|    select
			|	 case
			|	    when @@dateb < '"+Формат(ДатаС,"ДГГГГММДД")+"' then '"+Формат(ДатаС,"ДГГГГММДД")+"'
			|	    else @@dateb
			|	 end				     dateb,
			|	 case
			|	    when "+ИмяФункцииКонПериода+"(@@dateb)>@@datee then @@datee
			|	    else "+ИмяФункцииКонПериода+"(@@dateb)
			|	 end				     datee
			|
			|
			|    set @@dateb = dateadd("+стрDatePart+",1,@@dateb)
			|end
			|";

		КонецЕсли;

	КонецЕсли;

	RS.Отладка(фОтладка);

	рез = RS.Выполнить(ТекстЗапроса);
	Если рез = 0 Тогда
		Сообщить(RS.ПолучитьОписаниеОшибки());
		Возврат 0;
	КонецЕсли;

	Возврат 1;
КонецФункции	// ЗаполнитьТаблицуДат      


т.е., исходя из Дат Начала и Конца заполняем таблицу для выбранной периодичности, далее, когда строим основной запрос, делаем примерно следующее:
Код
Выбрать все
...
...
...
//добавляем формируем, запрос, исходя из группировок, которые выбрал пользователь, плюс дополнительно:
стрКолонки = стрКолонки + "
|(select
|   dateb
| from
|   #tmp_dates
| where
|   left(Рег.date_time_iddoc,8) between dateb and datee) dateb,";

....
....
....
//результат запроса инсертим во временную таблицу
ТекстЗапроса = "
|set nocount on
|insert into #Отчет_ХХХХХХ
|select
|  "+стрКолонкиГруппировки+",
|  "+стрКолонкиСумм+"
|from
| (
|  select
|   "+стрКолонки+"
|  from
|    $Регистр.YYYYYYY Рег (nolock)
|  where
| ) vt
|where
| "+стрУсловие+"
|group by
|  "+стрКолонкиГруппировки+"
|";
 


Далле саму перекрестную таблицу строим уже при выводе на печать. Определитель периода в основной таблице(таблице результата #Отчет_ХХХХХХ) у нас есть - dateb.
Надеюсь, что-то понятноУлыбка
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перекрестный запрос
Ответ #5 - 23. Июня 2010 :: 11:37
Печать  
Судя по тексту запроса, у тебя база SQL.
Так почему бы не воспользоваться консолью от тов. berezdetsky, которую он указал в первом же посту?
  
Наверх
 
IP записан
 
Anna
Junior Member
**
Отсутствует


1C++

Сообщений: 39
Зарегистрирован: 02. Декабря 2009
Пол: Женский
Re: Перекрестный запрос
Ответ #6 - 23. Июня 2010 :: 11:45
Печать  
Консолью.....мм а где ее скачать можно?
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Перекрестный запрос
Ответ #7 - 23. Июня 2010 :: 11:55
Печать  
Там же была ссылка http://www.1cpp.ru/forum/YaBB.pl?num=1193394153
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Перекрестный запрос
Ответ #8 - 23. Июня 2010 :: 12:00
Печать  
Здесь же просто нужна периодичность, т.е. нужно вывести все периоды. Даже, если не было данных(движений и т.п.) за этот период в источнике. Консоль запросов разве это умеет?Улыбка
  
Наверх
 
IP записан
 
Anna
Junior Member
**
Отсутствует


1C++

Сообщений: 39
Зарегистрирован: 02. Декабря 2009
Пол: Женский
Re: Перекрестный запрос
Ответ #9 - 23. Июня 2010 :: 13:10
Печать  
А не получится сделать так как нужно, используя выгрузку результата  имеющегося запроса в индексированную таблицу с последующей ее группировкой?
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать