Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Пример: при выборке задаем условие "WHERE table.code = @code", где @code - переменная. Очень неудобно, когда в значение переменной ничего не входит, т.е. условие не нужно. Неужели нету какого-нибудь "застолбленного" символа или обозначения, который бы помог решить эту проблему? А то IF-ами надоело уже строить логическое дерево до 5-го уровня... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 05:16 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Пояснение: например, можно было бы условие задать как "WHERE table.code = * " ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 05:18 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
where table.code = @code or @code is Null ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 05:18 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
to Garya: нет, "or" не поможет, по специфике запроса переменная @code - is not null ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 05:24 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Тогда поясни, чем определяется "когда в значение переменной ничего не входит, т.е. условие не нужно"?. Я в отчетах использую такой прием: перед выводом отчета запрашивается какой-либо параметр раскрывающимся списком, который например, может принимать либо значение конкретного клиента (товара, валюты, etc), либо "ВСЕ", либо группу такого. После выбора пользователем из списка этого параметра, в процедуру возвращается соответственно целочисленное Id клиента, ноль или Id группы с отрицательным значением. А запрос в процедуре будет выглядеть соответственно: ... where @client in (Client.Id, 0, -ClientGroup.Id) ... если без группы, а просто либо конкретный клиент, либо все, то ... where @client in (Client.Id, 0) ... Соответственной, большой и сложный отчет с кучей параметров будет выглядеть как ... where @client in (Client.Id, 0, -ClientGroup.Id) and @tovar in (Tovar.Id, 0, - TovarCategory) and @valut in (Valut.Id, 0) and ... Взяв себе это за практику, отчеты пишутся быстро и автоматически. На самом деле, это примерно тоже, что предложил Garya "where table.code = @code or @code is Null", только более систематизированный подход. Меня могут упрекнуть, в том что обилие альтернатив (in раскрывается в or) затрудняет работу оптимизатора и запрос получается не самым эффективным. Согласен с этим. Однако, бухгалтера, финансисты, менеджеры, etc привыкшие получать отчеты из галактики за 20-30 минут, ждут мои отчеты за 1-2 мин и считают это молниеносным. Там же где ожидание такого отчета превращается в проблему, я применяю другой подход: формирую в процедуре запрос динамически и выполняю exec'ом. Например, в условие where попадет "Client.Id=@client" только когда будет выбран конкретный клиент, а когда будет выбран "все клиенты", никакого условия по клиентам добавлено не будет. Запрос получается всегда самым эффективным. Однако, этим методом отчеты пишутся медленно, поэтому я им не злоупотребляю. Теперь ругайте: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 06:06 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
to Глеб Уфимцев: ругать не буду, буду спрашивать. У меня в процедуру, предположим, передается переменная кода товара @code. Она может принимать либо конкретное значение кода товара, либо 0, если товар не выбран (то есть отчет по всем товарам). У меня сейчас стоит IF и проверяет на условие IF @code=0, и в зависимости от этого в запрос добавляется условие или нет. Вопрос в том, можно ли при @code=0 заменять @code на что-нибудь, чтоб запросов было не 2, а 1 - универсальный. Т.е. если провести аналогию с моим примером, условие "WHERE @code=0" интерпретировалось как по всем кодам. З.Ы. Если ты и написал пример реализации подобного, попробуй тогда объяснить, как ты обходишь этот изъян, если у тебя товар не выбран и в процедуру, как и у меня, передается 0. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 06:22 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
в догонку: интересно, а как у тебя условия в запросе добавляются динамически. Ты делаешь строковую переменную и потом кидаешь ее на выполнение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 06:26 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Это как раз тот самый случай WHERE @code in (table.code, 0) При этом, если будет выбран конкретный товар, то условие выборки станет эквивалентно @code=table.code (или table.code=@code), а если будет выбран "все товары", то значение @code станет 0 и критерий будет эквивалентен where @code=0 ("0=0" = true), в выборку попадут все товары. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 06:31 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
О, доперло до меня. Слушай, классно придумано, даже ругать нечего! Ты, небось, раз галактику хаишь, тоже 1С под SQL затачивал, тогда будем знакомы,я - Petrovich. Спасибо за ценный совет... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 06:40 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Блин. А особенно классно придумано по поводу выбора группы. Этот минус просто генеален. Снимаю шляпу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 07:37 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
2:Глеб Уфимцев Я хочу поразрабатывать тему с группами. Предложенный метод (с минусом для группы) работает при 2-ух уровневом справочнике товаров: Группа->Товар А если он будет 3, 4 и т.д. N-уровневый справочник каких то характеристик. Как в таком случае можно организовать дубовую схему условия выборки? А если иерархия справочника не жестко задана количеством уровней, а в виде дерева несбалансированного? Мне кажется, что можно как то через строковые переменный, т.е. формировать строку из ID с каждого уровня, разделя их запятыми. Но что-то самую малость не сходится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 09:26 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Лазание по дереву - это отдельная увлекательная задача. К сожалению, малопроизводительная. Поэтому я её избегаю всеми правдами и неправдами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 09:48 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
2 zamm Для N-уровнего спрввочника еще проще create table #t( id int, parent int, name varchar(99)) select * from #t where @tovar in (id, parent) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 11:59 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
2:SergSuper А вот не проще. Твой примерчик выберет только два соседних уровня. А как выбрать 3 или 4. Тут уже не раз обсуждался вопрос о деревьях и о выборе целой ветви дерева в том числе. Не будем сейчас ее трогать. А вот класическая организация 3-уровнего справочника - 3 таблицы со связью один-ко-многим. Как должно выглядеть условие для отбора? ... where @client in (Client.Id, 0, -ClientGroup.Id) ... в данном случае минус уже не удасться использовать для отделения уровней. Можно например использовать заведомо большой мношитель, что-то типа ... where @client in (Client.Id, 0, ClientGroup1.Id*10000, ClientGroup2.Id*100) ... Но множители вещь не надежная. Ведь никогда не знаешь какого размера у тебя будет справочник, особено с какой нибудь номенклатурой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2001, 15:52 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Человеки, объясните, че-то въехать в гениальный минус перед группой не могу. Что дает конструкция "where @client = -ClientGroup.Id"? Ни разу с таким не сталкивался. Минус - это тоже какое-то фикс. значение типа "*"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.08.2001, 02:24 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Всё просто - если число положительное выбирается по коду клиента, если число отрицательное - по коду группы Client cln grp name 1 1 Vasya 2 1 Petya 3 2 Masha 4 2 Dusya create proc SelectClients @cln int As select * from Client where @cln in (cln,0,-grp) go exec SelectClients 2 -- выберется 2-й клиента exec SelectClients 0 -- выберутся все exec SelectClients -2 -- выберутся клиенты 3 и 4 Можно было бы настроить так, что номера групп и клиентов не пересекались бы(например задать identity для групп четные, а для и клиентов - нечетные ) и тогда можно передавать параметры и без минусов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.08.2001, 05:43 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Начинается все с формы, где оператор выбирает условия для фильтра - условно это комбобокс, где перечисленны наименования групп и товаров в этих группах. При формировании комбобокса ID товаров беруться простые числа, а ID групп с минусом что бы отличать товар от группы. Ведь группы и товары хранятся в разных таблицах и ID у них могут быть одинаковыми. Следующий шаг. Пользователь выбрал что-то и вызывается процедура, которой передается выбранное значение. Далее следует запрос, типа select * from Client left join ClientGroup on ClientGroup.ID = Client.GroupID ... where @client in (Client.Id, 0, -ClientGroup.Id) ... И запись попадет в выборку, если она относится к группе с ID=5, а не если сам товар имеет ID=5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.08.2001, 05:52 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Преклоняясь перед идеей использования "-" в in хочется отметить, что OR работают часто медленно. Хотя и не везде, конечно. Лучше (по скорости, но не по синтаксису использовать UNION вроде такого select * from Table where @code=0 union select * from Table where code=@code Сюда можно наворотить еще много чего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.08.2001, 09:08 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
В догонку к UNION: здесь же можно и "-" вполне приспособить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.08.2001, 09:10 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Сейчас не на чем собрать пример. Если не трудно, поясните - почему Union быстрее? Просто из спортивного ингтереса . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.08.2001, 16:29 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
to SergSuper и zamm: "Всё просто - если число положительное выбирается по коду клиента, если число отрицательное - по коду группы" - дык это мне программно отслеживать надо? Иначе не понимаю, как она найдет то поле, где хранится id группы, к которой относится товар (у меня и товар, и группы находятся в одном справочнике, и соответственно их id находятся в одной колонке)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2001, 00:45 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
Почему Union быстрее? Ну видимо оптимизатор его лучше обкарнывает. Т.е. например в таком случае последовательные запросы/Union или IF будут работать значительно (в разы) быстрее. Может правда и не буквально в таком - но в подобном. А если еще и условий поднаворотить, тогда уж точно. -- для ID исп. тип Uniqueidentifier - привычнее мне -- задаем один из параметров, по которым идет отбор: @ID1 или @ID2 или @ID3, остальные -- приравниваем NULL SELECT * FROM Table WHERE (@ID1=ID1 AND @ID1 IS NOT NULL) OR (@ID2=ID2 AND @ID2 IS NOT NULL) OR (@ID3=ID3 AND @ID3 IS NOT NULL) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2001, 04:05 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
2:Petrovich Я так понимаю, что у тебя что то типа 2-ух уровнего дерева ID Name ParID IsGr 1 Ложки 0 Y 2 Вилки 0 Y 3 Ложка Арт1 1 N 4 Ложка Арт2 1 N 5 Вилка Арт5 2 N 6 Вилка Арт6 2 N В данном случае тоже можно использовать минус. Минус ставится у клиента в меню, когда он должен выбрать какой фильтр ему наложить. некий условный код для формирвания формы пользователя while not rs.eof ... if rs.IsGr =Y then ' столо быть это группа menu.add(rs.name,-rs.id) else ' а это обычный товар в группе menu.add(rs.name,rs.id) end if rs.movenext end А в процедуре которая выдает результирующий набор будет следующий запрос select * from tovar where @kodtovara in (0,tovar.id,-tovar.parid) P/S/ Написал, а сам подумал о том, что в конкретном примере у первых двух записей ParID = 0 и это может както отразится на правильности условия in (0,...), но ведь 0 у нас обозначает "выбрать все", и поэтому,вроде бы, должно все правильно сработать. P.P.S. А то что UNION работает быстрее OR я тоже несколько раз убеждался, причем это "быстрее" измеряется в разы, бывали случаи что и на порядок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2001, 06:50 |
|
||
|
Альтернатива *
|
|||
|---|---|---|---|
|
#18+
to zamm: спасибо за совет, до конца еще не въехал во всю красоту описанной реализации нужного мне алгоритма, но стараюсь изо всех сил. Добавлю насчет "or" или "in" - у меня выборка с or создавалась за 9 мин., перевел ее на in - 4 секунды! Как объяснить такую разительную разницу, не знаю... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2001, 08:00 |
|
||
|
|

start [/forum/topic.php?fid=46&tid=1825917]: |
0ms |
get settings: |
9ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
31ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
75ms |
get tp. blocked users: |
1ms |
| others: | 224ms |
| total: | 380ms |

| 0 / 0 |
