Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) Запрос ограничивается количеством строк подзапроса (число прочтений - 4390 )
Андрюха
Junior Member
**
Отсутствует



Сообщений: 74
Местоположение: Красноярск
Зарегистрирован: 19. Марта 2008
Пол: Мужской
Запрос ограничивается количеством строк подзапроса
20. Августа 2008 :: 03:30
Печать  
Хочу получить последнюю цену поступления по некоторым номенклатурным позициям, но сталкиваюсь с проблемой, что условие "TOP Х" из подзапроса влияет не на количество отобраных записей в подзапросе, а на общее количество записей запроса в целом. Что я делаю не так?

Код
Выбрать все
ТекстЗапроса = "
|SELECT Номенклатура.ID [Ссылка $Справочник.Номенклатура]
|	, Подзапрос.ДатаПартии
|	, Подзапрос.Количество
|	, Подзапрос.СуммаРуб
|FROM $Справочник.Номенклатура AS Номенклатура
|	INNER JOIN (SELECT TOP 1 $ПартииНаличие.Номенклатура Номенклатура
|			, $ПартииНаличие.ДатаПартии ДатаПартии
|			, $ПартииНаличие.Количество Количество
|			, $ПартииНаличие.СуммаРуб СуммаРуб
|		FROM $Регистр.ПартииНаличие AS ПартииНаличие
|		WHERE ($ПартииНаличие.КодОперации = :КодОперации)
|		ORDER BY $ПартииНаличие.ДатаПартии DESC) AS Подзапрос ON Номенклатура.ID = Подзапрос.Номенклатура
|WHERE (Номенклатура.ID IN (SELECT val FROM #СписокНоменклатуры))
|";

рс.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура");
рс.УстановитьТекстовыйПараметр("КодОперации", Перечисление.КодыОпераций.Закупка); 

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


I Love YaBB 2!

Сообщений: 68
Зарегистрирован: 13. Ноября 2006
Re: Запрос ограничивается количеством строк подзап
Ответ #1 - 20. Августа 2008 :: 04:10
Печать  
в общем как то так...

Код
Выбрать все
ТекстЗапроса = "
|SELECT  $ПартииНаличие.Номенклатура [Ссылка $Справочник.Номенклатура]
|			, (select Max($ПартииНаличиеД.ДатаПартии) from $Регистр.ПартииНаличие as
| $ПартииНаличиеД where $ПартииНаличиеД.Номенклатура =$ПартииНаличие.Номенклатура)
|			, $ПартииНаличие.Количество Количество
|			, $ПартииНаличие.СуммаРуб СуммаРуб
|		FROM $Регистр.ПартииНаличие AS ПартииНаличие
|		WHERE ($ПартииНаличие.КодОперации = :КодОперации) and
|			($ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры))
|
|";

рс.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура");
рс.УстановитьТекстовыйПараметр("КодОперации", Перечисление.КодыОпераций.Закупка); 


  
Наверх
 
IP записан
 
Андрюха
Junior Member
**
Отсутствует



Сообщений: 74
Местоположение: Красноярск
Зарегистрирован: 19. Марта 2008
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #2 - 20. Августа 2008 :: 04:19
Печать  
g00d писал(а) 20. Августа 2008 :: 04:10:
Для начала оптимизируем запрос, убирем все лишнее

Ну допустим. Имеем теперь все записи по регистру по каждой номенклатуре, а хотелось - исключительно последние. Именно с этой целью там и сортировка по дате по убыванию, и TOP 1.

А с MAX в запрос попадут максимальные даты из регистра + все движения по номенклатуре списка.
  
Наверх
 
IP записан
 
g00d
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 68
Зарегистрирован: 13. Ноября 2006
Re: Запрос ограничивается количеством строк подзап
Ответ #3 - 20. Августа 2008 :: 05:00
Печать  
Цитата:
А с MAX в запрос попадут максимальные даты из регистра + все движения по номенклатуре списка.


или  как то так
Код
Выбрать все
ТекстЗапроса = "
|SELECT  $ПартииНаличие.Номенклатура [Ссылка $Справочник.Номенклатура]
|
|			,(select Max($ПартииНаличиеД.ДатаПартии)
|				, $ПартииНаличие.Количество Количество
|				, $ПартииНаличие.СуммаРуб СуммаРуб
|			    from $Регистр.ПартииНаличие as $ПартииНаличиеД
|				where $ПартииНаличиеД.Номенклатура =$ПартииНаличие.Номенклатура
|						and  $ПартииНаличиеД.ДатаПартии=Max($ПартииНаличиеД.ДатаПартии)
|
|		FROM $Регистр.ПартииНаличие AS ПартииНаличие
|		WHERE ($ПартииНаличие.КодОперации = :КодОперации) and
|			($ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры))
|
|";

рс.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура");
рс.УстановитьТекстовыйПараметр("КодОперации", Перечисление.КодыОпераций.Закупка);
 

  
Наверх
 
IP записан
 
Андрюха
Junior Member
**
Отсутствует



Сообщений: 74
Местоположение: Красноярск
Зарегистрирован: 19. Марта 2008
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #4 - 20. Августа 2008 :: 05:52
Печать  
g00d писал(а) 20. Августа 2008 :: 05:00:
ТекстЗапроса = "
|SELECT  $ПартииНаличие.Номенклатура [Ссылка $Справочник.Номенклатура]
|
|                  ,(select Max($ПартииНаличиеД.ДатаПартии)
|                        , $ПартииНаличие.Количество Количество
|                        , $ПартииНаличие.СуммаРуб СуммаРуб
|                      from $Регистр.ПартииНаличие as $ПартииНаличиеД
|                        where $ПартииНаличиеД.Номенклатура =$ПартииНаличие.Номенклатура
|                                    and  $ПартииНаличиеД.ДатаПартии=Max($ПартииНаличиеД.ДатаПартии)
|
|            FROM $Регистр.ПартииНаличие AS ПартииНаличие
|            WHERE ($ПартииНаличие.КодОперации = :КодОперации) and
|                  ($ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры))
|            
|";
     
рс.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура");
рс.УстановитьТекстовыйПараметр("КодОперации", Перечисление.КодыОпераций.Закупка);


Хорошее решение. Но вопрос остается открытым - почему TOP 1 во вложеном запросе не фурычит?
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #5 - 20. Августа 2008 :: 06:05
Печать  
TOP - предложение Transact-SQL ограничивающее размер Результирующего
набора строк заданным количеством строк ( можно задавать и в % ).
т.е top не применим в подзапросах, а действует только на выводимые куда либо строки на экран или в таблицу значений.
Лучше вообще стараться избегать top ( Я использую top только во время написания новых запросов для отладки).
В твоем случае можно использовать MAX(  $ПартииНаличиеД.ДатаПартии )

  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #6 - 20. Августа 2008 :: 06:16
Печать  
Z1 писал(а) 20. Августа 2008 :: 06:05:
top не применим в подзапросах, а действует только на выводимые куда либо строки на экран или в таблицу значений.


Смех
  

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


I Love YaBB 2!

Сообщений: 68
Зарегистрирован: 13. Ноября 2006
Re: Запрос ограничивается количеством строк подзап
Ответ #7 - 20. Августа 2008 :: 06:32
Печать  
Z1 писал(а) 20. Августа 2008 :: 06:05:
TOP - предложение Transact-SQL ограничивающее размер Результирующего
набора строк заданным количеством строк ( можно задавать и в % ).
т.е top не применим в подзапросах, а действует только на выводимые куда либо строки на экран или в таблицу значений.
Лучше вообще стараться избегать top ( Я использую top только во время написания новых запросов для отладки).
В твоем случае можно использовать MAX(  $ПартииНаличиеД.ДатаПартии )


а мне кажется все дело в INNER JOIN
  
Наверх
 
IP записан
 
Андрюха
Junior Member
**
Отсутствует



Сообщений: 74
Местоположение: Красноярск
Зарегистрирован: 19. Марта 2008
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #8 - 20. Августа 2008 :: 06:56
Печать  
g00d писал(а) 20. Августа 2008 :: 06:32:
а мне кажется все дело в INNER JOIN

Пробовал с LEFT JOIN - номенклатура попадает вся, но значения из регистра нулевые. Эксперимента ради менял значения TOP - с 45 запрос заработал как мне хочется, а с 999 - в запрос попадают другие записи из регистра (но по номенклатуре из списка).

Хочу понять логику.
  
Наверх
 
IP записан
 
g00d
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 68
Зарегистрирован: 13. Ноября 2006
Re: Запрос ограничивается количеством строк подзап
Ответ #9 - 20. Августа 2008 :: 08:00
Печать  
Цитата:
g00d писал(а) 20. Августа 2008 :: 06:32:
а мне кажется все дело в INNER JOIN

Пробовал с LEFT JOIN - номенклатура попадает вся, но значения из регистра нулевые. Эксперимента ради менял значения TOP - с 45 запрос заработал как мне хочется, а с 999 - в запрос попадают другие записи из регистра (но по номенклатуре из списка).

Хочу понять логику.


ИМХО ответ в том, каким образов JOINы соединяют таблицы
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #10 - 20. Августа 2008 :: 08:09
Печать  
Цитата:
Хочу понять логику.


Посмотри как работает $ПоследнееЗначение

  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
villy
Senior Member
****
Отсутствует



Сообщений: 287
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #11 - 20. Августа 2008 :: 11:42
Печать  
Цитата:
Цитата:
Хочу понять логику.


Посмотри как работает $ПоследнееЗначение


а чё там смотреть? работает как часы Подмигивание
  
Наверх
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #12 - 20. Августа 2008 :: 12:31
Печать  
Цитата:
а чё там смотреть? работает как часы Подмигивание


Поэтому и напесал  Подмигивание
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
Андрюха
Junior Member
**
Отсутствует



Сообщений: 74
Местоположение: Красноярск
Зарегистрирован: 19. Марта 2008
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #13 - 21. Августа 2008 :: 03:34
Печать  
g00d писал(а) 20. Августа 2008 :: 05:00:
ТекстЗапроса = "
|SELECT  $ПартииНаличие.Номенклатура [Ссылка $Справочник.Номенклатура]
|
|                  ,(select Max($ПартииНаличиеД.ДатаПартии)
|                        , $ПартииНаличие.Количество Количество
|                        , $ПартииНаличие.СуммаРуб СуммаРуб
|                      from $Регистр.ПартииНаличие as $ПартииНаличиеД
|                        where $ПартииНаличиеД.Номенклатура =$ПартииНаличие.Номенклатура
|                                    and  $ПартииНаличиеД.ДатаПартии=Max($ПартииНаличиеД.ДатаПартии)
|
|            FROM $Регистр.ПартииНаличие AS ПартииНаличие
|            WHERE ($ПартииНаличие.КодОперации = :КодОперации) and
|                  ($ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры))
|            
|";
     
рс.УложитьСписокОбъектов(СписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура");
рс.УстановитьТекстовыйПараметр("КодОперации", Перечисление.КодыОпераций.Закупка);


Довел идею до рабочей версии, но в результате опять получается не совсем то что хотелось бы:
Код
Выбрать все
ТекстЗапроса = "
	|SELECT  $ПартииНаличие.Номенклатура [Ссылка $Справочник.Номенклатура]
	|				, $ПартииНаличие.Количество Количество
	|				, $ПартииНаличие.СуммаРуб СуммаРуб
	|				, (SELECT MAX($ПартииНаличие1.ДатаПартии)
	|					FROM $Регистр.ПартииНаличие AS ПартииНаличие1
	|					WHERE ($ПартииНаличие1.Номенклатура = $ПартииНаличие.Номенклатура)
	|					GROUP BY $ПартииНаличие1.ДатаПартии
	|					HAVING ($ПартииНаличие1.ДатаПартии = MAX($ПартииНаличие1.ДатаПартии)))
	|		FROM $Регистр.ПартииНаличие AS ПартииНаличие
	|		WHERE ($ПартииНаличие.КодОперации = :КодОперации) and
	|			($ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры))
	|"; 



Выбираются все движения из регистра вместо самого последнего. Может чего не понял?
  
Наверх
 
IP записан
 
Андрюха
Junior Member
**
Отсутствует



Сообщений: 74
Местоположение: Красноярск
Зарегистрирован: 19. Марта 2008
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #14 - 21. Августа 2008 :: 06:50
Печать  
В итоге запрос выглядит вот так (работает правильно)
Код
Выбрать все
ТекстЗапроса = "
	|SELECT
	|	Номенклатура.ID [Ссылка $Справочник.Номенклатура] ,
	|
	|	(SELECT TOP 1 $ПартииНаличие.Количество Количество
	|	FROM $Регистр.ПартииНаличие AS ПартииНаличие
	|	WHERE ($ПартииНаличие.КодОперации = :КодОперации)
	|		AND  $ПартииНаличие.Номенклатура  =  Номенклатура.ID
	|	ORDER BY $ПартииНаличие.ДатаПартии DESC ),
	|
	|	(SELECT TOP 1 $ПартииНаличие.СуммаРуб СуммаРуб
	|	FROM $Регистр.ПартииНаличие AS ПартииНаличие
	|	WHERE ($ПартииНаличие.КодОперации = :КодОперации)
	|		AND  $ПартииНаличие.Номенклатура  =  Номенклатура.ID
	|	ORDER BY $ПартииНаличие.ДатаПартии DESC )
	|
	|FROM $Справочник.Номенклатура AS Номенклатура
	|WHERE Номенклатура.ID IN (SELECT val FROM #СписокНоменклатуры)
	|"; 

  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #15 - 21. Августа 2008 :: 08:44
Печать  
или так
Код
Выбрать все
SELECT
  Номенклатура.ID [Ссылка $Справочник.Номенклатура] ,
  $ПартииНаличие.ДатаПартии,
  $ПартииНаличие.Количество,
  $ПартииНаличие.СуммаРуб
FROM $Справочник.Номенклатура AS Номенклатура
LEFT JOIN (
  SELECT
    $ПартииНаличие.Номенклатура AS Номенклатура,
    MAX($ПартииНаличие.ДатаПартии) AS ДатаПоследнейПартии
  FROM $Регистр.ПартииНаличие AS ПартииНаличие
  WHERE $ПартииНаличие.КодОперации = :КодОперации
  GROUP BY $ПартииНаличие.Номенклатура
) AS ПоследниеПартии ON ПоследниеПартии.Номенклатура = Номенклатура.ID
LEFT JOIN $Регистр.ПартииНаличие AS ПартииНаличие ON $ПартииНаличие.КодОперации = :КодОперации
  AND $ПартииНаличие.Номенклатура = Номенклатура.ID
  AND $ПартииНаличие.ДатаПартии = ПоследниеПартии.ДатаПоследнейПартии
WHERE Номенклатура.ID IN (SELECT val FROM #СписокНоменклатуры) 

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


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос ограничивается количеством строк подзап
Ответ #16 - 21. Августа 2008 :: 10:29
Печать  
DmitrO писал(а) 21. Августа 2008 :: 08:44:
или так
Код
Выбрать все
SELECT
  Номенклатура.ID [Ссылка $Справочник.Номенклатура] ,
  $ПартииНаличие.ДатаПартии,
  $ПартииНаличие.Количество,
  $ПартииНаличие.СуммаРуб
FROM $Справочник.Номенклатура AS Номенклатура
LEFT JOIN (
  SELECT
    $ПартииНаличие.Номенклатура AS Номенклатура,
    MAX($ПартииНаличие.ДатаПартии) AS ДатаПоследнейПартии
  FROM $Регистр.ПартииНаличие AS ПартииНаличие
  WHERE $ПартииНаличие.КодОперации = :КодОперации
  GROUP BY $ПартииНаличие.Номенклатура
) AS ПоследниеПартии ON ПоследниеПартии.Номенклатура = Номенклатура.ID
LEFT JOIN $Регистр.ПартииНаличие AS ПартииНаличие ON $ПартииНаличие.КодОперации = :КодОперации
  AND $ПартииНаличие.Номенклатура = Номенклатура.ID
  AND $ПартииНаличие.ДатаПартии = ПоследниеПартии.ДатаПоследнейПартии
WHERE Номенклатура.ID IN (SELECT val FROM #СписокНоменклатуры) 



+10
-----------------------------------------------------------

для (0) твой внутр запрос
Код
Выбрать все
(SELECT TOP 1 $ПартииНаличие.Количество Количество
	|	FROM $Регистр.ПартииНаличие AS ПартииНаличие
	|	WHERE ($ПартииНаличие.КодОперации = :КодОперации)
	|		AND  $ПартииНаличие.Номенклатура  =  Номенклатура.ID
	|	ORDER BY $ПартииНаличие.ДатаПартии DESC )
 


сделает следущее получит ВЕСЬ набор, упорядочит его и только потом
оставит только первую строку - что есть очень неоптимально.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать