Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) ICASE и IIF (число прочтений - 9740 )
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
ICASE и IIF
13. Августа 2007 :: 11:57
Печать  
Возникла проблема с условием в селекте:

Код:
Код
Выбрать все
ICASE(((Журн.$ОбщийРеквизит.Автор = $Клиенты.Менеджер) AND
	   (1-($ПТ.НДС+$ПТ.Стоимость)/$ПТ.Оборот >= :Процент) AND
	   ($ПТ.КодОперации <> :КО)),1,0) as СуммаОборот 


работает абсолютно нормально... То есть в результате СуммаОборот = 1 или 0

А код:
Код
Выбрать все
ICASE(((Журн.$ОбщийРеквизит.Автор = $Клиенты.Менеджер) AND
	   (1-($ПТ.НДС+$ПТ.Стоимость)/$ПТ.Оборот >= :Процент) AND
	   ($ПТ.КодОперации <> :КО)),$ПТ.Оборот,0) as СуммаОборот 



возвращает все нули (хотя должны быть либо нули, либо значение "оборот"), и если сделать отдельно выборку по $ПТ.Оборот:
Код
Выбрать все
$ПТ.Оборот as СуммаОборот 


все выполняет правильно.
« Последняя редакция: 13. Августа 2007 :: 13:19 - Rubin »  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #1 - 13. Августа 2007 :: 12:38
Печать  
Я что-то не вижу отличий в этих запросах. Или плохо смотрю?
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3051
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #2 - 13. Августа 2007 :: 12:42
Печать  
а почему в первом >= :ПроцентЦифр , а во втором >= :Процент ?
  

1&&2&&3
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #3 - 13. Августа 2007 :: 13:18
Печать  
trad писал(а) 13. Августа 2007 :: 12:42:
а почему в первом >= :ПроцентЦифр , а во втором >= :Процент ?


))) Это одно и то же, не обращайте внимания

Разница:
1. ICASE(Условие,1,0) as СуммаОборот
2. ICASE(Условие,$ПТ.Оборот,0) as СуммаОборот
Где ПТ = регистр остатков (ПартииТоваров)

Первое условие, само собой нормально работает, а второе - никак
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #4 - 13. Августа 2007 :: 14:21
Печать  
А если нолик кастануть до типа $ПТ.Оборот?
  
Наверх
ICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: ICASE и IIF
Ответ #5 - 13. Августа 2007 :: 14:27
Печать  
Полностью скопируй условие из 1. и положи в 2.
Бываю проблемы со шрифтами.
Также проверь на IIF.

Присоединяюсь - 000000000000.00 думаю немного ускорит.
  
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #6 - 13. Августа 2007 :: 15:34
Печать  
Ну и в итоге?
  
Наверх
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #7 - 14. Августа 2007 :: 05:23
Печать  
Спасибо за подсказку. Всё заработало после того, как подставил "000000000000.00"  вместо "0"
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #8 - 14. Августа 2007 :: 05:48
Печать  
А отчего когда я пишу $0 вместе тех нулей в большом количетсве, пишет, что алиас не известен. Так и должно быть? (работаю с dbf базой).

И ещё небольшой оффтоп. Есть ли в FoxPro аналог какой-нить WITH ROLLUP?
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #9 - 14. Августа 2007 :: 06:05
Печать  
Такого алиаса нет. Это сделали просто для наглядности. После формирования текста запроса надо сделать так:
Код
Выбрать все
СтрЗаменить(ТекстЗапроса, "$0", "000000000000.00");  

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


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #10 - 14. Августа 2007 :: 06:06
Печать  
Ясно...
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #11 - 14. Августа 2007 :: 06:45
Печать  
а от "000000000000.00" точность не потеряется?
Может $ПТ.Оборот имеет больше 2 знаков после запятой?
  
Наверх
ICQ  
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #12 - 14. Августа 2007 :: 06:59
Печать  
spock писал(а) 14. Августа 2007 :: 06:45:
а от "000000000000.00" точность не потеряется?
Может $ПТ.Оборот имеет больше 2 знаков после запятой?


Да, кстати, есть и такое Улыбка
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: ICASE и IIF
Ответ #13 - 14. Августа 2007 :: 08:17
Печать  
Rubin писал(а) 14. Августа 2007 :: 05:48:
И ещё небольшой оффтоп. Есть ли в FoxPro аналог какой-нить WITH ROLLUP?


Увы Печаль
В принципе реализовать несложно, если была бы возможность сохранять промежуточный запрос
во временную таблицу в оперативке (не в файл! ).
Спрашивал на форуме sql.ru у foxpro-программистов - они не знают как это сделать в vfpoledb.
Разве что Spock что нибудь придумает Улыбка

Пока все дальнейшие операции - через метод группировать индексной таблицы.
Но к сожалению - инд. табл. не делает все операции доступные через запросы Печаль
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #14 - 14. Августа 2007 :: 08:24
Печать  
Код
Выбрать все
SELECT
	Автор as [Автор $Справочник.Пользователи],
	Отдел,
	СуммаВыдал,
	Приоритет
FROM (
	SELECT
		Журн.$ОбщийРеквизит.Автор as Автор,
		Сотр.ParentID as Отдел,
		SUM(ICASE($РН.ВыдалП=1, $РН.СуммаП, 000000000000.00)) as СуммаВыдал,
		2 as Приоритет
	FROM
		1SJourn as Журн
	INNER JOIN
		$Документ.РасходнаяНакладная as РН On РН.IDDoc = Журн.IDDoc  
	INNER JOIN
		$Справочник.Пользователи as Сотр On Сотр.ID = Журн.$ОбщийРеквизит.Автор  
	WHERE
	Журн.IDDocDef = $ВидДокумента.РасходнаяНакладная AND
		Журн.Date BETWEEN {d :ДатаНач} AND {d :ДатаКон} AND
		Журн.Closed = 1 AND
		$РН.ВыдалП = 1 AND
		$РН.ДатаП >= {d :ДатаНач1} AND $РН.ДатаП <= {d :ДатаКон1} AND
		Журн.$ОбщийРеквизит.Автор IN "+Условия+"
	GROUP BY
		Автор, Отдел, Приоритет

	UNION ALL

	SELECT
		Сотр.ParentID as Автор,
		Сотр.ParentID as Отдел,
		SUM(ICASE($РН.ВыдалП=1, $РН.СуммаП, 000000000000.00)) as СуммаВыдал,
		1 as Приоритет
	FROM
		1SJourn as Журн
	INNER JOIN
		$Документ.РасходнаяНакладная as РН On РН.IDDoc = Журн.IDDoc  
	INNER JOIN
		$Справочник.Пользователи as Сотр On Сотр.ID = Журн.$ОбщийРеквизит.Автор  
	WHERE
		Журн.IDDocDef = $ВидДокумента.РасходнаяНакладная AND
		Журн.Date BETWEEN {d :ДатаНач} AND {d :ДатаКон} AND
		Журн.Closed = 1 AND
		$РН.ВыдалП = 1 AND
		$РН.ДатаП >= {d :ДатаНач1} AND $РН.ДатаП <= {d :ДатаКон1} AND
		Журн.$ОбщийРеквизит.Автор IN "+Условия+"
	GROUP BY
		Автор, Отдел, Приоритет
	) tmp
ORDER BY Отдел, Приоритет 



Я делаю это так.. ))) Просто хотел узнать, есть ли возможность заменить кучу писанины одной командой. Да и на быстродйествие наверное влияет... ((
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: ICASE и IIF
Ответ #15 - 14. Августа 2007 :: 08:58
Печать  
1. UNION лишнее
лучше приоритет как вычислямое выражение.
2. Куча INNER JOIN когда достаточно LEFT
3. Куча дополнительных условий, которые ни на что не влияют
4. Самое главное - у 1SJourn есть индекс IDDoc   
Т.е. базовой (секция FROM) должна быть РасходнаяНакладная и уже к ней прицеплять
1SJourn по IDDoc.
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #16 - 14. Августа 2007 :: 09:05
Печать  
Самое интересное, что работает )) а какие условия лишние?

И вообще. Можно поподробнее? В чем плохи INNER JOIN, как можно сделать приоритет в данном случае вычисляемым выражением? А про

Цитата:
Т.е. базовой (секция FROM) должна быть РасходнаяНакладная и уже к ней прицеплять
1SJourn по IDDoc.

вообще не понял (((. Выборка происходит по документам, какая разница, расходные прицеплять к журналу или наоборот? от этого что ли быстрее заработает?
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #17 - 14. Августа 2007 :: 10:51
Печать  
kiruha писал(а) 14. Августа 2007 :: 08:17:
Разве что Spock что нибудь придумает Улыбка

Забить на foxpro и перейти на MSSQL Улыбка
Или на провайдер Advantage, там можно писать #TempTbl
  
Наверх
ICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ICASE и IIF
Ответ #18 - 14. Августа 2007 :: 11:17
Печать  
spock писал(а) 14. Августа 2007 :: 10:51:
kiruha писал(а) 14. Августа 2007 :: 08:17:
Разве что Spock что нибудь придумает Улыбка

Забить на foxpro и перейти на MSSQL Улыбка
Или на провайдер Advantage, там можно писать #TempTbl

Кстати, сколько не искал материала по оптимизации запросов, везде идут крохами, по разным разделам рукоблудств. Может есть какая-нить "плотная" статья?
  
Наверх
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: ICASE и IIF
Ответ #19 - 16. Августа 2007 :: 00:19
Печать  
Rubin писал(а) 14. Августа 2007 :: 09:05:
Самое интересное, что работает )) а какие условия лишние?

И вообще. Можно поподробнее? В чем плохи INNER JOIN, как можно сделать приоритет в данном случае вычисляемым выражением? А про

Цитата:
Т.е. базовой (секция FROM) должна быть РасходнаяНакладная и уже к ней прицеплять
1SJourn по IDDoc.

вообще не понял (((. Выборка происходит по документам, какая разница, расходные прицеплять к журналу или наоборот? от этого что ли быстрее заработает?

Лишние условие -
Код
Выбрать все
Журн.IDDocDef = $ВидДокумента.РасходнаяНакладная 

, требует от драйвера доп.
проверки, но ввиду того, что есть соединение с РасходнаяНакладная - ничего нового не дает.

  Когда ты ставишь INNER - это означает, что после присоединения таблицы драйвер должен сделать
еще один проход и убрать записи отсутствующие во второй таблице. Если этих записей нет - то просто лишний прогон.

1SJourn - самая большая таблица в системе. В твоем запросе она целиком и дважды тащится на клиента.
Почему не написать -
Код
Выбрать все
FROM
$Документ.РасходнаяНакладная as РН
LEFT JOIN 1SJourn as Журн
		 On Журн.IDDoc=РН.IDDoc    


В этом случае у тебя считается только часть таблицы 1SJourn, т.к. у 1SJourn есть индекс IDDoc

Как у тебя UNion убрать не знаю, т.к. не понял Цитата:
Сотр.ParentID as Автор,
           Сотр.ParentID as Отдел,
Отдел и Автор одно и то же?
  
Наверх
 
IP записан
 
Rubin
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 70
Зарегистрирован: 31. Июля 2007
Re: ICASE и IIF
Ответ #20 - 16. Августа 2007 :: 07:13
Печать  
Спасибо за полезные сведения Улыбка Я в уже углубился в процесс оптимизации )))
Я думаю, можно написать так:

Код
Выбрать все
SELECT
	Автор as [Автор $Справочник.Пользователи],
	Отдел,
	СуммаВыдал,
	Приоритет
FROM (
	SELECT
		Сотр.ID as Автор,
		Сотр.ParentID as Отдел,
		SUM(ICASE($РН.ВыдалП=1, $РН.СуммаП, 000000000000.00)) as СуммаВыдал,
		2 as Приоритет
	FROM
		$Справочник.Пользователи as Сотр
	INNER JOIN
		1SJourn as Журн On Сотр.ID = Журн.$ОбщийРеквизит.Автор  
			and Журн.Date BETWEEN {d :ДатаНач} AND {d :ДатаКон}
			and Журн.Closed = 1 AND
			and Журн.$ОбщийРеквизит.Автор IN "+Условия+"
	INNER JOIN
		$Документ.РасходнаяНакладная as РН On РН.IDDoc = Журн.IDDoc  
			and $РН.ВыдалП = 1
			and $РН.ДатаП >= {d :ДатаНач1} AND $РН.ДатаП <= {d :ДатаКон1}
	GROUP BY
		Автор, Отдел, Приоритет

	UNION ALL

	SELECT
		Сотр.ParentID as Автор,
		Сотр.ParentID as Отдел,
		SUM(ICASE($РН.ВыдалП=1, $РН.СуммаП, 000000000000.00)) as СуммаВыдал,
		1 as Приоритет
	FROM
		$Справочник.Пользователи as Сотр
	INNER JOIN
		1SJourn as Журн On Сотр.ID = Журн.$ОбщийРеквизит.Автор  
			and Журн.Date BETWEEN {d :ДатаНач} AND {d :ДатаКон}
			and Журн.Closed = 1 AND
			and Журн.$ОбщийРеквизит.Автор IN "+Условия+"
	INNER JOIN
		$Документ.РасходнаяНакладная as РН On РН.IDDoc = Журн.IDDoc  
			and $РН.ВыдалП = 1
			and $РН.ДатаП >= {d :ДатаНач1} AND $РН.ДатаП <= {d :ДатаКон1}
	GROUP BY
		Автор, Отдел, Приоритет
	) tmp
ORDER BY Отдел, Приоритет  



Но от UNION ALL я не придумал ещё как избавиться, хотя желательно..
Этот запрос выполняет что-то вроде WITH ROLLUP.
Первый запрос выбирает значения с детализацией по автору, второй - значения с детализацией по группе автора с соответствующей суммой по ней. Когда эти таблицы объединяются и упорядочиваются по отделу и приоритету получается примерно такая весчь:
1      Отдел продажи      Отдел продажи      Сумма по отделу
2      Отдел продажи      Иванов            Сумма
2      Отдел продажи      Петров            Сумма
1      Отдел закупки      Отдел закупки      Сумма по отделу
2      Отдел закупки      Сидоров            Сумма

А вот если б кто придумал, как это сделать без объединения.........................
« Последняя редакция: 16. Августа 2007 :: 08:26 - Rubin »  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать