Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Как получить структуру справочника пр. запросом? (число прочтений - 9218 )
chicago
Senior Member
****
Отсутствует


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Как получить структуру справочника пр. запросом?
20. Июля 2006 :: 07:51
Печать  
Как можно получить структуру (или иерархию) справочника используя прямой запрос к бд?
Справочник - 7 уровней.
Для вывода итогов полученых в запросе по группам.
  
Наверх
ICQ  
IP записан
 
КилоГрамм
Senior Member
****
Отсутствует


Таити, Таити...

Сообщений: 434
Зарегистрирован: 14. Июня 2006
Пол: Мужской
Re: Как получить структура справочника пр. запросо
Ответ #1 - 20. Июля 2006 :: 07:58
Печать  
"Структура" - это что?
  

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


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как получить структура справочника пр. запросо
Ответ #2 - 20. Июля 2006 :: 08:14
Печать  
Цитата:
"Структура" - это что?



ГрупаУровня1 №1
    ГрупаУровня2 №1
       ГрупаУровня3 №1
           Елемент №1
           Елемент №2
    ГрупаУровня2 №2
       Елемент №3
и тд.

Под этим понимаем структуру (или иерархию) справочника.
  
Наверх
ICQ  
IP записан
 
КилоГрамм
Senior Member
****
Отсутствует


Таити, Таити...

Сообщений: 434
Зарегистрирован: 14. Июня 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #3 - 20. Июля 2006 :: 09:38
Печать  
  

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


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #4 - 24. Июля 2006 :: 07:41
Печать  
Для справочника ТМЦ у которого есть 4 группы (по иерархии) + елементы.
Вот так
Код
Выбрать все
|SELECT

|CASE
|	WHEN ТабТМЦ.РівТМЦ = 1 THEN ТабТМЦ.НаТ_01 + '#' + ТабТМЦ.ІдТ_01 + '#'
|	WHEN ТабТМЦ.РівТМЦ = 2 THEN ТабТМЦ.НаТ_02 + '#' + ТабТМЦ.ІдТ_02 + '#'
|	WHEN ТабТМЦ.РівТМЦ = 3 THEN ТабТМЦ.НаТ_03 + '#' + ТабТМЦ.ІдТ_03 + '#'
|	WHEN ТабТМЦ.РівТМЦ = 4 THEN ТабТМЦ.НаТ_04 + '#' + ТабТМЦ.ІдТ_04 + '#'
|	ELSE '1'
|END AS ГрТ_01,
|CASE
|	WHEN ТабТМЦ.РівТМЦ = 2 THEN ТабТМЦ.НаТ_01 + '#' + ТабТМЦ.ІдТ_01 + '#'
|	WHEN ТабТМЦ.РівТМЦ = 3 THEN ТабТМЦ.НаТ_02 + '#' + ТабТМЦ.ІдТ_02 + '#'
|	WHEN ТабТМЦ.РівТМЦ = 4 THEN ТабТМЦ.НаТ_03 + '#' + ТабТМЦ.ІдТ_03 + '#'
|	ELSE '2'
|END AS ГрТ_02,
|CASE
|	WHEN ТабТМЦ.РівТМЦ = 3 THEN ТабТМЦ.НаТ_01 + '#' + ТабТМЦ.ІдТ_01 + '#'
|	WHEN ТабТМЦ.РівТМЦ = 4 THEN ТабТМЦ.НаТ_02 + '#' + ТабТМЦ.ІдТ_02 + '#'
|	ELSE '3'
|END AS ГрТ_03,
|CASE
|	WHEN ТабТМЦ.РівТМЦ = 4 THEN ТабТМЦ.НаТ_01 + '#' + ТабТМЦ.ІдТ_01 + '#'
|	ELSE '4'
|END AS ГрТ_04,

|ТабТМЦ.НаТЕле + '#' + ТабТМЦ.ІдТЕле + '#' AS ТМЦЕле,
|ТабТМЦ.ІдТЕле AS ІдТЕле

|FROM (

|SELECT
|CASE
|	WHEN (ДовТ04.ID IS NOT NULL) AND (ДовТ03.ID IS NOT NULL) AND (ДовТ02.ID IS NOT NULL) AND (ДовТ01.ID IS NOT NULL) THEN 4
|	WHEN (ДовТ03.ID IS NOT NULL) AND (ДовТ02.ID IS NOT NULL) AND (ДовТ01.ID IS NOT NULL) THEN 3
|	WHEN (ДовТ02.ID IS NOT NULL) AND (ДовТ01.ID IS NOT NULL) THEN 2
|	WHEN (ДовТ01.ID IS NOT NULL) THEN 1
|	ELSE 0
|END AS РівТМЦ,

|ДовТ04.ID AS ІдТ_04,
|ДовТ03.ID AS ІдТ_03,
|ДовТ02.ID AS ІдТ_02,
|ДовТ01.ID AS ІдТ_01,

|ДовТ04.DESCR AS НаТ_04,
|ДовТ03.DESCR AS НаТ_03,
|ДовТ02.DESCR AS НаТ_02,
|ДовТ01.DESCR AS НаТ_01,

|ДовТМЦ.DESCR AS НаТЕле,
|ДовТМЦ.ID AS ІдТЕле

|FROM
|$Справочник.ТМЦ ДовТМЦ (nolock)
|LEFT JOIN $Справочник.ТМЦ ДовТ01 (nolock) ON ДовТМЦ.PARENTID = ДовТ01.ID
|LEFT JOIN $Справочник.ТМЦ ДовТ02 (nolock) ON ДовТ01.PARENTID = ДовТ02.ID
|LEFT JOIN $Справочник.ТМЦ ДовТ03 (nolock) ON ДовТ02.PARENTID = ДовТ03.ID
|LEFT JOIN $Справочник.ТМЦ ДовТ04 (nolock) ON ДовТ03.PARENTID = ДовТ04.ID

|WHERE
|ДовТМЦ.ISFOLDER = 2
 


кажись работает.
  
Наверх
ICQ  
IP записан
 
Scorpion
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 32
Местоположение: Киев
Зарегистрирован: 05. Июня 2006
Пол: Мужской
Re: Как получить структуру справочника
Ответ #5 - 28. Июля 2006 :: 09:52
Печать  
Используй рекурсивный вызов хранимой процедуры
  
Наверх
 
IP записан
 
chicago
Senior Member
****
Отсутствует


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как получить структуру справочника
Ответ #6 - 28. Июля 2006 :: 11:02
Печать  
Scorpion писал(а) 28. Июля 2006 :: 09:52:
Используй рекурсивный вызов хранимой процедуры


Такое не предлагать  Улыбка.
  
Наверх
ICQ  
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #7 - 28. Июля 2006 :: 12:48
Печать  
А вот и мой вариант:
udf-функция
Код
Выбрать все
IF EXISTS(SELECT name FROM sysobjects WHERE name = 'Expand_SC196' AND type = 'TF') DROP FUNCTION Expand_SC196
GO

CREATE FUNCTION Expand_SC196 (@CurID char(9))
RETURNS @retTbl TABLE ([ID] char(9), [LEVEL] int, [ROW_ID] int IDENTITY(1, 1))
AS
BEGIN
	DECLARE @strTbl TABLE (
		[ID] char(9) NOT NULL,
		[LEVEL] int NOT NULL,
		[ROW_ID] int IDENTITY(1, 1) NOT NULL
	)

	DECLARE @level as int
	SET @level = 1

	INSERT INTO @strTbl (id, level) VALUES (@CurID, @level)

	WHILE @level > 0 BEGIN
		IF EXISTS (SELECT * FROM @strTbl WHERE level = @level) BEGIN
			SELECT TOP 1
				@CurID = id
			FROM @strTbl
			WHERE level = @level
			ORDER BY row_id

			INSERT INTO @retTbl (id, level) VALUES(@CurID, @level-1)

			DELETE FROM @strTbl WHERE (level = @level) AND (id = @CurID)

			INSERT INTO @strTbl (id, level)
				SELECT id, @level + 1
				FROM SC196 (NOLOCK)
				WHERE parentid = @CurID
				ORDER BY isfolder, descr -- сортировка по наименованию, можно заменить на другое поле

			IF @@ROWCOUNT > 0 SET @level = @level + 1
		END
		ELSE
			SET @level = @level - 1
	END
RETURN
END
GO
 



А вот вызов:
Код
Выбрать все
SELECT
	dTbl.level as Уровень,
	dTbl.id as ID,
	ISNULL(SC.code, '< ... >') as Код,
	(SPACE((dTbl.level-1)*2) + ISNULL(SC.descr, '< ... >')) as Наименование, --чтоб красиво было :)
	ISNULL(SC.isfolder, 2) as ЭтоГруппа
FROM
	dbo.Expand_SC196('     0   ') as dTbl -- выводим все от корня, или можно указать какой-нибудь другой ID
LEFT JOIN SC196 as SC (NOLOCK) ON SC.id = dTbl.id
WHERE
	dTbl.id != '     0   '
ORDER BY
	dTbl.row_id -- порядок сортировки уже был указан в функции, тут только перестраховка
 

  
Наверх
ICQ  
IP записан
 
SSSnake
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 16
Зарегистрирован: 18. Сентября 2007
Re: Как получить структуру справочника пр. запросо
Ответ #8 - 18. Сентября 2007 :: 07:39
Печать  
Как вариант могу предложить, получение остатков с иерархией по ТМЦ:

[code]      Запрос = СоздатьОбъект("ODBCRecordSet");
     СтркУслТМЦ="";
     Если ВыбТМЦ.РазмерСписка()<>0 Тогда
           СтркУслТМЦ="AND ТМЦ IN (SELECT Val FROM #ГруппаТ_П)";
           Запрос.УложитьСписокОбъектов(ВыбТМЦ, "#ГруппаТ_П", "ТМЦ");
     КонецЕсли;
         СтркУслСклад="";
     Если ВыбСклады.РазмерСписка()<>0 Тогда
           СтркУслСклад="AND Склад IN (SELECT Val FROM #ГруппаС_П) ";
           Запрос.УложитьСписокОбъектов(ВыбСклады, "#ГруппаС_П", "Склады");
     КонецЕсли;
     
     Запрос.УстановитьТекстовыйПараметр("ВыбФирма", ПолучитьПустоеЗначение("Справочник.Фирмы"));

   

     ТекстЗапросаП = "
     |SELECT
     |  Рег.Склад [Склад $Справочник.Склады]
     |, nz.ID [ТМЦ $Справочник.ТМЦ]
     |, CASE when nz.ID = n1.ID then Рег.Партия else NULL end [Партия $Справочник.Партии]
     |, SUM(Рег.КвоОстаток) КвоКонОст
     |, SUM(Рег.СуммаОснОстаток) СуммаОснКонОст
     |, MAX(CASE
     |   when nz.ID = n5.ID then LTrim(n5.Code)
     |   when nz.ID = n4.ID AND n5.ID is not null then LTrim(n5.Code)+'/'+LTrim(n4.Code)
     |   when nz.ID = n4.ID AND n5.ID is null then LTrim(n4.Code)
     |      when nz.ID = n3.ID AND n5.ID is not null then LTrim(n5.Code)+'/'+LTrim(n4.Code)+'/'+LTrim(n3.Code)
     |      when nz.ID = n3.ID AND n5.ID is null AND n4.ID is not null then LTrim(n4.Code)+'/'+LTrim(n3.Code)
     |   when nz.ID = n3.ID AND n5.ID is null AND n4.ID is null then LTrim(n3.Code)
     |      when nz.ID = n2.ID AND n5.ID is not null then LTrim(n5.Code)+'/'+LTrim(n4.Code)+'/'+LTrim(n3.Code)+'/'+LTrim(n2.Code)
     |      when nz.ID = n2.ID AND n5.ID is null AND n4.ID is not null then LTrim(n4.Code)+'/'+LTrim(n3.Code)+'/'+LTrim(n2.Code)
     |      when nz.ID = n2.ID AND n5.ID is null AND n4.ID is null AND n3.ID is not null then LTrim(n3.Code)+'/'+LTrim(n2.Code)
     |   when nz.ID = n2.ID AND n5.ID is null AND n4.ID is null AND n3.ID is null then LTrim(n2.Code)
     |   when nz.ID = n1.ID AND n5.ID is not null then m(n1.Code)
     |      when nz.ID = n1.ID AND n5.ID is null AND n4.ID is not null then LTrim(n4.Code)+'/'+LTrim(n3.Code)+'/'+LTrim(n2.Code)+'/'+LTrim(n1.Code)
     |      when nz.ID = n1.ID AND n5.ID is null AND n4.ID is null AND n3.ID is not null then LTrim(n3.Code)+'/'+LTrim(n2.Code)+'/'+LTrim(n1.Code)
     |      when nz.ID = n1.ID AND n5.ID is null AND n4.ID is null AND n3.ID is null AND n2.ID is not null then LTrim(n2.Code)+'/'+LTrim(n1.Code)
     |   when nz.ID = n1.ID AND n5.ID is null AND n4.ID is null AND n3.ID is null AND n2.ID is null then LTrim(n1.Code)
     |   else '--'
     |end) as ПКод //полный код
     |FROM
     |  $РегистрОстатки.Остатки(,,
     |              Фирма = :ВыбФирма "+СтркУслСклад+СтркУслТМЦ+",
     |            (Фирма,ТМЦ,Склад,Партия), (Кво, СуммаОсн)) as Рег
     |LEFT join $Справочник.ТМЦ as n1 on n1.ID = Рег.ТМЦ 
     |LEFT join $Справочник.ТМЦ as n2 on n2.ID = n1.ParentID
     |LEFT join $Справочник.ТМЦ as n3 on n3.ID = n2.ParentID
     |LEFT join $Справочник.ТМЦ as n4 on n4.ID = n3.ParentID
     |LEFT join $Справочник.ТМЦ as n5 on n5.ID = n4.ParentID
     |LEFT join $Справочник.ТМЦ as nz on (nz.ID = n1.ID OR nz.ID = n2.ID OR nz.ID = n3.ID OR nz.ID = n4.ID OR nz.ID = n5.ID)
     |GROUP BY Рег.Склад, nz.ID , CASE when nz.ID = n1.ID then Рег.Партия else NULL end
     |ORDER BY 1, 6
     |";[/code]

прошу совета, можно ли зделать проще и/или быстрее
  
Наверх
 
IP записан
 
yudin
Full Member
***
Отсутствует


Краткость - с.т.

Сообщений: 131
Местоположение: Ростов - на - Дону
Зарегистрирован: 25. Мая 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #9 - 25. Сентября 2007 :: 10:40
Печать  
Группировать с помощью индексированной таблицы не нравится?
  

С уваженьем, дата, подпись
Наверх
wwwICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как получить структуру справочника пр. запросо
Ответ #10 - 25. Сентября 2007 :: 11:33
Печать  
yudin писал(а) 25. Сентября 2007 :: 10:40:
Группировать с помощью индексированной таблицы не нравится?


На больших выборках ИТ начинает ощутимо притормаживать.
И MAX(MIN),Count нет поддержки. И группы упорядычиваются по коду (по основному представлению?) без опций,
а нужно иногда - по наименованию или реквизиту (для прайса, например).
  
Наверх
 
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #11 - 25. Сентября 2007 :: 18:31
Печать  
yudin писал(а) 25. Сентября 2007 :: 10:40:
Группировать с помощью индексированной таблицы не нравится?


http://infostart.ru/profile/10604/projects/1145/

вот тут мы уже экспериментировали таким образом.

на 26 тысячах элементов номенклатуры (моя стандартная база для запуска тестов производительности)
Тормоза ощутимые.

ЗЫ НО это для DBF
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
yudin
Full Member
***
Отсутствует


Краткость - с.т.

Сообщений: 131
Местоположение: Ростов - на - Дону
Зарегистрирован: 25. Мая 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #12 - 01. Октября 2007 :: 14:16
Печать  
Там в инструкции написано что надо еще родителя выдернуть, чтобы быстрее было.. С родителем значительно быстрее на 25тысячах элементах, 8 уровней вложенности
  

С уваженьем, дата, подпись
Наверх
wwwICQ  
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Как получить структуру справочника пр. запросо
Ответ #13 - 02. Октября 2007 :: 05:39
Печать  
SSSnake писал(а) 18. Сентября 2007 :: 07:39:
прошу совета, можно ли зделать проще и/или быстрее

Если очень нужна скорость вычислений то по моему гораздо эфективней хранить
структуру подчиненности т.е. храним Родитель1,Родитель2, Родитель3 ... Родитель10
для каждого элемента ( и папки ) справочника. ( Если извесно что уровней не
более 5 то создаем только до Родитель5).
Только надо корректировать это отношение при смене родителя, но так как элементы не очень часто перекидываются между папками то это не должно быть большой проблемой.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать