Имя: Пароль:
1C
 
Множественный фильтр
Ø
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 забыл ВТ обозвать.
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn