![]() |
![]() |
![]() |
|
Множественный фильтр Ø |
☑ | ||
---|---|---|---|---|
0
SMakcik
14.02.06
✎
06:58
|
Привет Всем!
Интересует такой вопрос, можно ли в SQL запросе построить множественный фильтр? Понимает ли запрос 1С-ий вариант (... в СЗ)? |
|||
1
Юрикс
14.02.06
✎
08:15
|
select *
from t where id IN (select id from #t) |
|||
2
SMakcik
14.02.06
✎
08:34
|
И как это понимать?
И что такое t и #t? |
|||
3
Vaicartana
14.02.06
✎
08:38
|
не понимает.
Делай либо через ...IN(SELECT... FROM tmp) либо через IN ("+Условия+") где Условия - это некоторый текстовый список. Например словием вхождением в группу ВыбТМЦ будет соответсвовать условие WHERE спр.ParentID IN (' няняня',' няняня',' няняня') но для этого условие нужно предварительно подотовить так, чтобы из ВыбТМЦ получить список всех ее подгрупп. |
|||
7
Vaicartana
14.02.06
✎
08:54
|
тогда добавляется еще одно условие
WHERE (спр.ParentID IN (' няняня',' няняня',' няняня')) OR (спр.ID IN (' ляляля',' ляляля',' ляляля')) одно ограничение: SQL запрос не резиновый, если список ОЧЕНЬ БОЛЬШОЙ или развернутый справочник имеет много уровней, то лучше его во временнуб таблицу tmp загнать. Но вообще нафиг нужно такое огромное колво вхождений в IN, может лучше тогда сам подзапрос (см 1) по условиям настроить? |
|||
8
Денис2
14.02.06
✎
09:04
|
Во, нашёл у себя...
Если списТоваров.РазмерСписка() > 0 Тогда RecordSet.УложитьСписокОбъектов(списТоваров, "#Tovs", "Номенклатура"); КонецЕсли; RecordSet.УстановитьТекстовыйПараметр("ДатаРасчета", ПолучитьДатуТА()); RecordSet.УстановитьТекстовыйПараметр("Просрочка", колДней); текстЗапроса = " |select Товар as [Товар $Справочник.Номенклатура], ПоСчету as [Счет $Документ.Счет], РезервТовараОстаток |,Cast(Left(журн.DATE_TIME_IDDOC,8) as DateTime) as ДатаДок |from |$РегистрОстатки.РезервыТоваров(,"; Если списТоваров.РазмерСписка() > 0 Тогда текстЗапроса = текстЗапроса + " |inner join #Tovs on Товар = #Tovs.val,"; иначе текстЗапроса = текстЗапроса + ","; КонецЕсли; текстЗапроса = текстЗапроса + " |, |(Товар,ПоСчету),РезервТовара) as Резервы |inner join _1sjourn as журн |on журн.IDDOC = Резервы.ПоСчету |where DateDiff(day, Cast(Left(журн.DATE_TIME_IDDOC,8) as DateTime), :ДатаРасчета)>=:Просрочка"; |
|||
9
Vaicartana
14.02.06
✎
09:07
|
так ты на 1С++ делаешь? Ну, дык, там есть метод Запрос.УложитьСписокОбъектов() правда он слегка тормоз.
Лучше смотреть на количество товаров и групп(вместе с подгруппами) и на основании этого делать анализ. Если больше 100шт, то лучше в tmp, если меньше, то в текст. При оч. больших выборках лучше менять консерваторию. Тобишь делать подзапрос, который возвращает список Товаров. . По поводу двух регистров: Не уверен, что ВТ ее поддерживает. Попробуй без нее, либо уточни на itland.ru Как вариант - UNION ALL, но с ВТ может и не работать, не проверял. . По фирмам лучше сделать вот так: СписокФирм=СоздатьОбъект("СписокЗначений"); Если ВыбРазделитель.Выбран()=1 Тогда Если ВидРазделителя=2 Тогда //фирма СписокФирм.ДобавитьЗначение(ВыбРазделитель); Иначе СпрФирм=СоздатьОбъект("Справочник.Фирмы"); СпрФирм.ВыбратьЭлементы(); Пока СпрФирм.ПолучитьЭлемент() = 1 Цикл Если ((СпрФирм.ЮрЛицо=ВыбРазделитель) и (ВидРазделителя=3)) или //Юрлицо ((СпрФирм.УпрАналитика=ВыбРазделитель) и (ВидРазделителя=4)) Тогда //УпрАналитика СписокФирм.ДобавитьЗначение(СпрФирм.ТекущийЭлемент()); КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если СписокФирм.РазмерСписка()>0 Тогда ТекстСпискаФирм="("; Для Н=1 По СписокФирм.РазмерСписка() Цикл ТекстСпискаФирм=ТекстСпискаФирм+"'"+МД.ЗначениеВСтрокуБД(СписокФирм.ПолучитьЗначение(Н))+"'"+?(Н=СписокФирм.РазмерСписка(),")",","); КонецЦикла; КонецЕсли; . Ну а дальше как обычно WHERE $Регистр.ОстаткиТМЦ.Фирма IN (ТекстСпискаФирм) ну или гдето так... |
|||
12
Юрикс
14.02.06
✎
09:21
|
(10) да, до запроса
|
|||
13
Vaicartana
14.02.06
✎
09:26
|
пример тут.
http://itland.ru/forum/index.php?showtopic=14200 . Любые группировки задаются в GROUP BY, ну а отображение уже твоя задача. |
|||
15
Vaicartana
14.02.06
✎
09:35
|
Дык, ты прежде чем группировку указывать в SELECT определил Фирму или нет?
Если по твоем запросу судить - то нет! |
|||
18
Денис2
14.02.06
✎
09:46
|
(17)УложитьСписок() сама её создаст. Ты, главное, имя дай #TableName
|
|||
20
Vaicartana
14.02.06
✎
09:54
|
JOIN не нужен.
У регистра уже есть фирма, используй ее, а в условии примени то, что я тебе в 9 показал |
|||
22
Vaicartana
14.02.06
✎
11:06
|
блин, да я же грю: не нужен!!!!
У тебя регистр содержит Фирму, зачем тебе лишний JOIN? |
|||
23
Юрикс
14.02.06
✎
11:36
|
(21) перед запуском запроса сделай Запрос.Отладка(1), увидишь какой запрос уходит на сервер
|
|||
25
Юрикс
14.02.06
✎
11:49
|
(24) еще раз прочитай (9)
|
|||
27
Vaicartana
14.02.06
✎
11:58
|
2 (24) блин, ну понятно, что если ты СВОЙ запрос выполнишь будет ругаться.
Ведь регистр не знает о "Фирма.УпрАналитика", он только о "Фирма" знает! Ты INNER JOIN для того и делаешь, чтобы связь с УпрАналитикой сделать! Но в моем запросе (9) ЭТОГО ДЕЛАТЬ НЕ НАДО!!!! Т.Е, ты просто пишешь SELECT Фирма AS [Фирма $Справочник.Фирмы], ... FROM ... WHERE Фирма IN (МоёУсловие) GROUP BY Фирма, ... |
|||
29
Vaicartana
14.02.06
✎
12:05
|
если ты о фирмах = то однозначна WHERE
Текстовые условия мгновенны, а для JOIN'а надо время |
|||
31
Vaicartana
15.02.06
✎
07:06
|
2 (30) не совсем понятно что имеется ввиду. Класс требуется зарегистрировать либо в defcls.prm, либо во встроенной обработке defcls.
Сам класс можно менять как угодно в процессе работы 1С-ки и не выходя из нее. Только должен быть выключен режим "оптимизация" на закладке 1С++ |
|||
33
Vaicartana
15.02.06
✎
08:57
|
в defcls.prm вносишь ОДИН РАЗ строку
class ИмяКласса=МойКласс.ert { } . И потом в любом месте своего отчета МойКласс=СоздатьОбъект("ИмяКласса"); |
|||
35
Vaicartana
15.02.06
✎
09:02
|
он создается в каталоге базы.
Читай доку, там это описано в самом начале. |
|||
37
Vaicartana
15.02.06
✎
09:11
|
ну на вскидку - не правильно задан путь к "Склад". Приведи полный ТСКЛ текст, через Запрос.Отладка(1);
|
|||
39
Юрикс
15.02.06
✎
09:15
|
(38) выборки из остатков и резервов нужно объединить при помощи "union all"
т.е. вместо "as ОстаткиТМЦ," надо "as ОстаткиТМЦ union all" |
|||
40
Юрикс
15.02.06
✎
09:20
|
сорри проглядел, совет в 38 не полон, давай уточним что тебе нужно в результате - и остатки и резервы отдельно или достаточно свободного остатка?
|
|||
41
Юрикс
15.02.06
✎
09:23
|
мда.. сплю видимо еще.. в (40) была конечно же речь про совет в (39)
|
|||
44
Юрикс
15.02.06
✎
09:34
|
в общем схема такая
если нужны остатки за минусом резерва то делаешь так select ... from (select tovar, kolvo from ostatki union all select tovar, -kolvo from rezerv ) svob_ostatki group by.. если нужны отдельно остатки и резервы, то так select ... from (select tovar, ost, 0 as rez from ostatki union all select tovar, 0 as ost, rez from rezerv ) svob_ostatki group by.. |
|||
45
Vaicartana
15.02.06
✎
09:35
|
нет связи таблиц.
Я ж тебе писал еще в (9) . А вообще очень странный запрос. Где регистр оборотов RA? Или у тебя отчет на начало месяца? |
|||
46
nicxxx
15.02.06
✎
09:35
|
//**************************************************************************************
Функция глПроверкаНаличияSQL(Конт) Экспорт ИтогиАктуальны = Конт.ИтогиАктуальны(); Если ИтогиАктуальны = 0 Тогда RecordSet.УстановитьТекстовыйПараметр("ДатаРасчета", СформироватьПозициюДокумента(Конт.ТекущийДокумент(),-1)); //Сообщить("Итоги неактуальны"); КонецЕсли; RecordSet.УстановитьТекстовыйПараметр("ВыбФирма", Конт.Фирма); RecordSet.УстановитьТекстовыйПараметр("ВыбСклад", Конт.Склад); RecordSet.УстановитьТекстовыйПараметр("ВыбДок", Конт.ТекущийДокумент()); RecordSet.УстановитьТекстовыйПараметр("Услуга", Перечисление.ВидыНоменклатуры.Услуга); ТекстЗапроса = " |SELECT | $Док.Номенклатура as [Номенклатура $Справочник.Номенклатура], | SUM($Док.Количество*$Док.Коэффициент) as Количество, | MIN(Рег.КоличествоОстаток) as КолОст, | 0 as КолРез |FROM | $ДокументСтроки." + Конт.Вид() + " as Док (nolock) |LEFT JOIN | $РегистрОстатки.ОстаткиТМЦ(" +?(ИтогиАктуальны = 0, ":ДатаРасчета~", "") + ", | INNER JOIN | (SELECT DISTINCT | $Д1.Номенклатура as _Номенклатура | FROM $ДокументСтроки." + Конт.Вид() + " as Д1 (nolock) | WHERE Д1.IDDOC = :ВыбДок) Д ON | Д._Номенклатура = Номенклатура, | Склад = :ВыбСклад AND Фирма = :ВыбФирма, | (Номенклатура), (Количество)) as Рег ON $Док.Номенклатура = Номенклатура | |LEFT JOIN $Справочник.Номенклатура СпрН (nolock) ON СпрН.ID = $Док.Номенклатура | |WHERE | Док.IDDOC = :ВыбДок | AND | $СпрН.ВидНоменклатуры <> :Услуга |GROUP BY | $Док.Номенклатура |/*HAVING | SUM($Док.Количество*$Док.Коэффициент) > ISNULL(MIN(Рег.КоличествоОстаток),0)*/ |"; ТекстЗапроса=ТекстЗапроса+" |UNION ALL | |SELECT | $Док.Номенклатура as [Номенклатура $Справочник.Номенклатура], | /*SUM($Док.Количество*$Док.Коэффициент)*/ 0 as Количество, | 0 as КолОст, | MIN(РегРез.КоличествоОстаток) as КолРез |FROM | $ДокументСтроки." + Конт.Вид() + " as Док (nolock) |LEFT JOIN | $РегистрОстатки.РезервыТМЦ(" +?(ИтогиАктуальны = 0, ":ДатаРасчета~", "") + ", | INNER JOIN | (SELECT DISTINCT | $Д2.Номенклатура as __Номенклатура | FROM $ДокументСтроки." + Конт.Вид() + " as Д2 (nolock) | WHERE Д2.IDDOC = :ВыбДок) _Д ON | _Д.__Номенклатура = Номенклатура, | Склад = :ВыбСклад AND Фирма = :ВыбФирма, | (Номенклатура), (Количество)) as РегРез ON $Док.Номенклатура = Номенклатура | |LEFT JOIN $Справочник.Номенклатура СпрН (nolock) ON СпрН.ID = $Док.Номенклатура | |WHERE | Док.IDDOC = :ВыбДок AND | $СпрН.ВидНоменклатуры <> :Услуга | |GROUP BY | $Док.Номенклатура | |/*HAVING | SUM($Док.Количество*$Док.Коэффициент) > ISNULL(MIN(РегРез.КоличествоОстаток),0)*/"; ТЗ = глПолучитьВыборку(, ТекстЗапроса); ТЗ.Свернуть("Номенклатура", "Количество, КолОст, КолРез"); Если ТЗ.КоличествоСтрок()<>0 Тогда ТЗ.ВыбратьСтроки(); Пока ТЗ.ПолучитьСтроку()=1 Цикл Если ТЗ.Количество<=(ТЗ.КолОст-ТЗ.КолРез) Тогда ТЗ.УдалитьСтроку(); ТЗ.ВыбратьСтроки(); КонецЕсли; КонецЦикла; Если ТЗ.КоличествоСтрок()<>0 Тогда Возврат ТЗ; КонецЕсли; Возврат 1; Иначе Возврат 1; КонецЕсли; |
|||
50
Vaicartana
15.02.06
✎
12:26
|
2 (49) это к DmitrO вопрос. Они там что то с оптимизацией намутили.
|
|||
52
Vaicartana
15.02.06
✎
12:44
|
если в запросе только RG - то ессно не правильные остатки будут.
Только в случае остатков на начало периода (первое число месяца) остатки будут правильные. Регистр оборотов RA для того и нужен, чтобы посмотреть остаток на произвольную дату. |
|||
54
Юрикс
15.02.06
✎
13:06
|
(53) а после 21.01 движения есть?
|
|||
56
Vaicartana
16.02.06
✎
04:02
|
2 (55) а не делаешь ли ты перед запросом "РасчитатьРегистрыНа(По)"?
|
|||
59
Юрикс
16.02.06
✎
07:09
|
(57)
1. SELECT Склад, Номенклатура, Количество FROM (SELECT Склад AS [Склад $Справочник.Склады] - задал новый псевдоним, а на уровне выше используешь другой 2. посмотри еще раз (44), у тебя ненужные подзапросы и группировка непонятно где |
|||
61
Юрикс
16.02.06
✎
07:21
|
покажи исправленный вариант
|
|||
63
Юрикс
16.02.06
✎
08:05
|
(62) где ж ты исправил-то? надо так
SELECT [Склад $Справочник.Склады], [Номенклатура $Справочник.Номенклатура], SUM(КоличествоОстаток) AS Количество и в (59) обрати на п.2! зы: убери ты к черту эти SUM на нижних уровнях.. |
|||
65
Юрикс
16.02.06
✎
08:41
|
(64) ну дык конечно, ты объединяешь уже сгруппированные таблицы, а надо сначала объединить, а уж потом группировать :)
короче, должно быть типа такого SELECT Склад [Склад $Справочник.Склады], Номенклатура [Номенклатура $Справочник.Номенклатура], SUM(КоличествоОстаток) Количество FROM ( select rg405_vt.sp408 as Номенклатура, rg405_vt.sp418 as Склад, rg405_vt.sp411 as КоличествоОстаток from rg405 as rg405_vt (nolock) LEFT JOIN sc4014 СпрФирмы ON СпрФирмы.ID = rg405_vt.sp4062 where rg405_vt.period={d '2006-02-01'} and (rg405_vt.sp411 <> 0) and (СпрФирмы.sp4012 = ' 1 ') and sp408 IN (SELECT val FROM #ВремТМЦ) UNION ALL select rg4480_vt.sp4477 as Номенклатура, rg4480_vt.sp4476 as Склад, -rg4480_vt.sp4479 as КоличествоОстаток from rg4480 as rg4480_vt (nolock) LEFT JOIN sc4014 СпрФирмы ON СпрФирмы.ID = rg4480_vt.sp4475 where rg4480_vt.period={d '2006-02-01'} and (rg4480_vt.sp4479 <> 0) and (СпрФирмы.sp4012 = ' 1 ') and sp4477 IN (SELECT val FROM #ВремТМЦ) ) tbl GROUP BY Склад,Номенклатура HAVING SUM(КоличествоОстаток) <> 0; |
|||
67
Vaicartana
16.02.06
✎
09:07
|
2 (66) ты вообще не понимаешь, что ты пишешь?
Где алиасы твоих подзапросов? |
|||
70
Юрикс
16.02.06
✎
09:12
|
(66) лишнии скобки и лишнее Where
"and (СпрФирмы.sp4012 = ' 1 ') ) as WHERE Номенклатура IN (SELECT val FROM #ВремТМЦ) " исправь на "and (СпрФирмы.sp4012 = ' 1 ') and Номенклатура IN (SELECT val FROM #ВремТМЦ)" причем вместо НОМЕНКЛАТУРА поставь реальное имя поля номенклатуры в каждом подзапросе зы: посмотри внимательнее (65) зыы: и убери лишние поля в выборках: фирмы, цены и т.д. |
|||
72
Юрикс
16.02.06
✎
09:26
|
(71) смотреть строку 19, найти rg405_vt, много думать
|
|||
75
Юрикс
16.02.06
✎
09:49
|
(74) что значит вылетает? сам по себе что ли материализуется?
|
|||
77
Vaicartana
16.02.06
✎
10:06
|
2 (75) это метапарсер ставит, а SMakcik забыл ВТ обозвать.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |