Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Помогите новичку (число прочтений - 4008 )
Kalen
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Помогите новичку
29. Марта 2010 :: 12:52
Печать  
Помогите, пожалуйста, дописать запрос.
Задачка:
Дано:
1. Справочник Договоры
2. Справочник Спецификации, подчиненный договорам. Есть поле ДатаСпецификации.
3. Справочник ТоварыСпецификации, подчиненный спецификациям. Есть поля Товар (ссылка) и Цена.
Требуется: Получить список товаров с ценами, действующими на заданную дату.

Для заданного товара написал такой запрос:
Код
Выбрать все
SELECT
	Спец.ID AS ТекСпец,
	Спец.ДатаСпец AS ДатаСпец,
	Спр.Товар AS Товар
FROM [Справочник.ТовСпецДог] AS Спр
INNER JOIN
	[Справочник.Спецификации] AS Спец
	ON Спр.PARENTEXT = Спец.ID
		AND Спец.ДатаСпец <= '20100327' AND Спец.PARENTEXT = '    B3   '
WHERE Спр.Товар='   4BJ   ' AND Спец.ДатаСпец =
	(SELECT
		MAX(ДатаСпец1) FROM (
			SELECT
				Спец1.ДатаСпец AS ДатаСпец1,
				Спр1.Товар AS Товар1
			FROM [Справочник.ТовСпецДог] AS Спр1
			INNER JOIN
				[Справочник.Спецификации] AS Спец1
				ON Спр1.PARENTEXT = Спец1.ID
					AND Спец1.ДатаСпец <= '20100327' AND Спец1.PARENTEXT = '    B3   '
			WHERE Спец1.ДатаСпец<='20100327' AND Товар1='   4BJ   ')) 


Выдает ссылку на последнюю спецификацию, где встречается этот товар.

Как получить полный список товаров?
« Последняя редакция: 29. Марта 2010 :: 17:08 - Kalen »  

_____3.txt ( 0 KB | Загрузки )
Наверх
GTalkICQ  
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Помогите новичку
Ответ #1 - 29. Марта 2010 :: 14:08
Печать  
Если хотите помощи то пишите запросПолностью  через 1с++ со всеми
значениями параметров в текущем ответе  через теги
code /code
Также непонятно что вы хотите получить если товар входит в разные договора  и есть на него разные цены
то какую цену или цены Вы хотите получить ?
  
Наверх
 
IP записан
 
Kalen
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #2 - 29. Марта 2010 :: 17:19
Печать  
Z1 писал(а) 29. Марта 2010 :: 14:08:
пишите запросПолностью  через 1с++

боюсь, что не понял. пример можно?
Цитата:
со всеми значениями параметров

вроде бы значения все в тексте
Цитата:
через теги code /code

нет проблем. Мне просто показалось так места много занимает.
Цитата:
Также непонятно что вы хотите получить если товар входит в разные договора  и есть на него разные цены
то какую цену или цены Вы хотите получить ?

Ограничимся одним договором.
  
Наверх
GTalkICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите новичку
Ответ #3 - 29. Марта 2010 :: 18:26
Печать  
Kalen писал(а) 29. Марта 2010 :: 12:52:
Требуется: Получить список товаров с ценами, действующими на заданную дату.

Kalen писал(а) 29. Марта 2010 :: 17:19:
Ограничимся одним договором.

Код
Выбрать все
select $ТоварыСпецификации.Товар Товар
	, $ТоварыСпецификации.Цена Цена
from $Справочник.ТовСпецДог ТоварыСпецификации (nolock)
	inner join $Справочник.Спецификации Спецификации (nolock) on ТоварыСпецификации.parentext = Спецификации.id
	inner join (
			select $ТоварыСпецификации.Товар Товар
				, Max($Спецификации.ДатаСпец) ДатаСпец
			from $Справочник.ТовСпецДог ТоварыСпецификации (nolock)
				inner join $Справочник.Спецификации Спецификации (nolock) on ТоварыСпецификации.parentext = Спецификации.id
			where ($Спецификации.ДатаСпец <= :ВыбДата)
				and (Спецификации.parentext = :ВыбДоговор)
			group by $ТоварыСпецификации.Товар
		) sq on ($ТоварыСпецификации.Товар = sq.Товар) and ($Спецификации.ДатаСпец = sq.ДатаСпец)
where (Спецификации.parentext = :ВыбДоговор)
 

  

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


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #4 - 30. Марта 2010 :: 07:04
Печать  
berezdetsky писал(а) 29. Марта 2010 :: 18:26:
Код
Выбрать все
.....
select $ТоварыСпецификации.Товар Товар
	, Max($Спецификации.ДатаСпец) ДатаСпец
.....
	group by $ТоварыСпецификации.Товар
..... 


эх, я ведь как-то так пробовал, но, видать что-то упустил Улыбка
Огромное спасибо  Круглые глаза Я еще не раз буду вчитываться в этот код
  
Наверх
GTalkICQ  
IP записан
 
Kalen
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #5 - 30. Марта 2010 :: 08:11
Печать  
Еще заметил, что, похоже, задаю лишние условия. Т.е. если добавим фильтр помеченных на удаление товаров и спецификаций, то достаточно будет указать его только в подзапросе. Так?
[code]select $ТоварыСпецификации.Товар Товар
     , $ТоварыСпецификации.Цена Цена
from $Справочник.ТовСпецДог ТоварыСпецификации (nolock)
     inner join $Справочник.Спецификации Спецификации (nolock) on ТоварыСпецификации.parentext = Спецификации.id
     inner join (
                 select $ТоварыСпецификации.Товар Товар
                       , Max($Спецификации.ДатаСпец) ДатаСпец
                 from $Справочник.ТовСпецДог ТоварыСпецификации (nolock)
                       inner join $Справочник.Спецификации Спецификации (nolock) on ТоварыСпецификации.parentext = Спецификации.id
                 where ($Спецификации.ДатаСпец <= :ВыбДата)
                       and (Спецификации.parentext = :ВыбДоговор)
                       and (Спецификации.ISMARK <> '*') and (ТоварыСпецификации.ISMARK <> '*')
                 group by $ТоварыСпецификации.Товар
           ) sq on ($ТоварыСпецификации.Товар = sq.Товар) and ($Спецификации.ДатаСпец = sq.ДатаСпец)
where (Спецификации.parentext = :ВыбДоговор)
[/code]
Это оптимально?
  
Наверх
GTalkICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите новичку
Ответ #6 - 30. Марта 2010 :: 09:19
Печать  
[quote author=Kalen link=1269867155/0#5 date=1269936718]если добавим фильтр помеченных на удаление товаров и спецификаций, то достаточно будет указать его только в подзапросе. Так?[/quote]
Для товаров - да, для спецификаций - нет.
[hr]Для ИБ в формате sql тип поля ismark - bit, принимает значения 0 или 1.
  

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


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #7 - 30. Марта 2010 :: 09:50
Печать  
berezdetsky писал(а) 30. Марта 2010 :: 09:19:
для спецификаций - нет

так ведь работает же  Озадачен что не так?
Цитата:
Для ИБ в формате sql тип поля ismark - bit, принимает значения 0 или 1.

Да, спасибо, я знаю. У меня дбф.
  
Наверх
GTalkICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите новичку
Ответ #8 - 30. Марта 2010 :: 09:57
Печать  
Kalen писал(а) 30. Марта 2010 :: 09:50:
berezdetsky писал(а) 30. Марта 2010 :: 09:19:
для спецификаций - нет

так ведь работает же  Озадачен что не так?

Если на нужную дату будет две спецификации, из которых одна удалённая, то данные будут получены из обеих.

Kalen писал(а) 30. Марта 2010 :: 09:50:
Цитата:
Для ИБ в формате sql тип поля ismark - bit, принимает значения 0 или 1.

Да, спасибо, я знаю. У меня дбф.

Тогда, как минимум, стóит убрать хинт nolock.
  

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


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #9 - 30. Марта 2010 :: 10:10
Печать  
berezdetsky писал(а) 30. Марта 2010 :: 09:57:
Если на нужную дату будет две спецификации, из которых одна удалённая, то данные будут получены из обеих.

Уже наткнулся на это Подмигивание
Цитата:
Тогда, как минимум, стóит убрать хинт nolock.

А чем он чреват?
А как максимум?
  
Наверх
GTalkICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите новичку
Ответ #10 - 30. Марта 2010 :: 10:30
Печать  
Kalen писал(а) 30. Марта 2010 :: 10:10:
Цитата:
Тогда, как минимум, стóит убрать хинт nolock.

А чем он чреват?

Для DBF он не имеет смысла.

Kalen писал(а) 30. Марта 2010 :: 10:10:
А как максимум?

А хз. Я DBF-ные базы вижу только по праздникам и на картинках.
  

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


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #11 - 30. Марта 2010 :: 12:00
Печать  
Ну, я дальше пошел...
Поскольку в ТоварахСпецификации на самом деле может быть ссылка как на элемент Товаров, так и на группу, разворачиваю так:
Код
Выбрать все
select
	CASE
		WHEN CASE WHEN Тов.ISFOLDER = 1 THEN 1 ELSE 0 END=0 THEN ТоварыСпецификации.Товар
		WHEN Уровень2.ID ISNULL THEN Уровень1.ID
		WHEN Уровень3.ID ISNULL THEN Уровень2.ID
		WHEN Уровень4.ID ISNULL THEN Уровень3.ID
		WHEN Уровень5.ID ISNULL THEN Уровень4.ID
		ELSE Уровень5.ID END Товар1
	,ТоварыСпецификации.Цена Цена
from [Справочник.ТовСпецДог] ТоварыСпецификации
	inner join [Справочник.Спецификации] Спецификации  on ТоварыСпецификации.parentext = Спецификации.id
	left join [Справочник.Товары] Тов ON ТоварыСпецификации.Товар = Тов.ID
	left join [Справочник.Товары] AS Уровень1 ON Уровень1.PARENTID = ТоварыСпецификации.Товар
	left join [Справочник.Товары] AS Уровень2 ON Уровень2.PARENTID = Уровень1.ID
	left join [Справочник.Товары] AS Уровень3 ON Уровень3.PARENTID = Уровень2.ID
	left join [Справочник.Товары] AS Уровень4 ON Уровень4.PARENTID = Уровень3.ID
	left join [Справочник.Товары] AS Уровень5 ON Уровень5.PARENTID = Уровень4.ID
	inner join (
		select
			CASE
				WHEN CASE WHEN Тов.ISFOLDER = 1 THEN 1 ELSE 0 END=0 THEN ТоварыСпецификации.Товар
				WHEN Уровень2.ID ISNULL THEN Уровень1.ID
				WHEN Уровень3.ID ISNULL THEN Уровень2.ID
				WHEN Уровень4.ID ISNULL THEN Уровень3.ID
				WHEN Уровень5.ID ISNULL THEN Уровень4.ID
				ELSE Уровень5.ID END Товар
			,max(Спецификации.ДатаСпец) ДатаСпец
		from [Справочник.ТовСпецДог] ТоварыСпецификации
			inner join [Справочник.Спецификации] Спецификации  on ТоварыСпецификации.parentext = Спецификации.id
			left join [Справочник.Товары] Тов ON ТоварыСпецификации.Товар = Тов.ID
			left join [Справочник.Товары] AS Уровень1 ON Уровень1.PARENTID = ТоварыСпецификации.Товар
			left join [Справочник.Товары] AS Уровень2 ON Уровень2.PARENTID = Уровень1.ID
			left join [Справочник.Товары] AS Уровень3 ON Уровень3.PARENTID = Уровень2.ID
			left join [Справочник.Товары] AS Уровень4 ON Уровень4.PARENTID = Уровень3.ID
			left join [Справочник.Товары] AS Уровень5 ON Уровень5.PARENTID = Уровень4.ID
		where (Спецификации.ДатаСпец <= :ВыбДата)
			and (Спецификации.parentext = :ВыбДоговор) AND (CASE WHEN ТоварыСпецификации.ISMARK = '*' THEN 1 ELSE 0 END=0) AND (CASE WHEN Спецификации.ISMARK = '*' THEN 1 ELSE 0 END=0)
		group by Товар
	  ) sq on (Товар1 = sq.Товар) and (Спецификации.ДатаСпец = sq.ДатаСпец)
where (Спецификации.parentext = :ВыбДоговор)
 


это правда, что весь код следует постить таким образом? Может-таки текстовик аттачить?

Правильно?
Можно как-нибудь упростить?
А еще возникает проблема с типизацией Товар1 Печаль Если пишу
Код
Выбрать все
as [Товар1 $Справочник.Товары] 

получаю
no such column: Товар1
  
Наверх
GTalkICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите новичку
Ответ #12 - 30. Марта 2010 :: 12:18
Печать  
Kalen писал(а) 30. Марта 2010 :: 12:00:
Поскольку в ТоварахСпецификации на самом деле может быть ссылка как на элемент Товаров, так и на группу,

И одна цена на пять уровней номенклатуры?  Ужас


Kalen писал(а) 30. Марта 2010 :: 12:00:
Можно как-нибудь упростить?

Да - убрать этот фееричный join из подзапроса. Заодно исправится твоя ошибка.
  

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


1C++ rocks!

Сообщений: 185
Зарегистрирован: 29. Марта 2010
Пол: Мужской
Re: Помогите новичку
Ответ #13 - 30. Марта 2010 :: 12:37
Печать  
Цитата:
И одна цена на пять уровней номенклатуры?

Ну, да. Мне, конечно, стоило сказать, что в поле Цена в ТоварахСпецификации вообще-то может быть конкретное значение (рубли), а может и значние скидки на категорию цены, ссылка на которую указана еще в одном реквизите ТоваровСпецификации. Но пока речь не об этом Подмигивание. С группами товаров разобраться бы... Впрочем, на первый взляд код рабочий, только кучерявый.
Итак, если учесть вышесказанное, что можно удалить/написать лучше?
  
Наверх
GTalkICQ  
IP записан
 
Ярослав
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 43
Местоположение: Иркутск
Зарегистрирован: 14. Октября 2008
Re: Помогите новичку
Ответ #14 - 05. Апреля 2010 :: 05:16
Печать  
Я так понял нужно получать родителя самого верхнего уровня, то тогда попробуй использовать функции:

Код
Выбрать все
Функция НайтиФункцию(ИмяФункции)

	RS=СоздатьОбъект("ODBCRecordSet");
	ТекстНайтиФункцию = "                                                                    
	|select
	|case
	|	when exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[" + ИмяФункции + "]') and xtype in (N'FN', N'IF', N'TF'))
	|	then 1
	|	else 0
	|end";
	К = RS.ВыполнитьСкалярный(ТекстНайтиФункцию);//Тут скалярный, т.к. получаем только 1 или 0

	Возврат К;

КонецФункции

Функция УдалитьФункцию(ИмяФункции)

	RS=СоздатьОбъект("ODBCRecordSet");
	ТекстУдалитьФункцию = "
	|IF EXISTS(SELECT name FROM sysobjects WHERE name = '" + ИмяФункции + "') DROP FUNCTION "+ ИмяФункции;
	RS.ВыполнитьИнструкцию(ТекстУдалитьФункцию);

КонецФункции

Функция СоздатьФункцию(ИмяФункции)  

	//Использование dbo.Rod_1_Level(СпрТовары.ID) as [РодительФункция $Справочник.Номенклатура]
	RS=СоздатьОбъект("ODBCRecordSet");
	ТекстСоздатьФункцию = "
	|CREATE FUNCTION "+ ИмяФункции + "
	|		(
	|				@TovarID CHAR(9)  --Исходный элемент
	|		)
	|		RETURNS CHAR(9) --Возвращаем один ид
	|AS                                                        
	|BEGIN
	|
	|DECLARE @Result char(9)	--Где у нас будет результат
	|DECLARE @Parent char(9)	--Родитель
	|SET @Parent = @TovarID
	|
	|		WHILE @Parent != $ПустойИД --Пока родитель не пустой
	|		BEGIN
	|
	|			SELECT @Parent = ParentId FROM SC84 WHERE id = @Parent --Получаем родителя
	|       	IF @Parent != $ПустойИД
	|       	BEGIN
	|				SET @Result = @Parent
	|			END
	|		END
	|
	|		RETURN  @Result
	|END
	|";
	RS.ВыполнитьИнструкцию(ТекстСоздатьФункцию);
        
КонецФункции
 




Потом в коде пишешь
|     dbo.Rod_1_Level(СпрТовары.ID) as [РодительФункция $Справочник.Номенклатура]
И получаешь родителя верхнего уровня
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать