-
Есть таблица посещений (код клиента, дата визита):
CREATE TABLE VISIT_HISTORY( ID_CLIENT INTEGER NOT NULL, VISIT_DATE DATE NOT NULL );
Можно ли составить запрос тех клиентов, кто не посещал в эти дни. Именно запрос, а не процедуру (процедуру я сделаю). Тоесть надо взять все даты из истории посещений, всех клиентов и вывести тех, кого в который день небыло.
Просто интересно стало есть ли такая возможнось. БД Firebird. Если нет, то сделаю хранимкой, но все же чисто из интереса
-
А разве процедура не есть запрос?
-
Декартово произведение таблицы уникальных клиентов с таблицей уникальных клиентов, оставив только тех, кого в конкретный день не было.
-
> таблицы уникальных клиентов с таблицей уникальных клиентов
Пардон, пересечение клиентов с датами, конечно.
-
>Омлет (21.10.09 04:21) [3] а если такой даты нет в visit_history?)
-
> [0] zorik © (20.10.09 23:24) > Есть таблица посещений
А таблица клиентов есть? Если есть, то NOT EXISTS клиентов в посещениях вернет тебе прогульщиков.
-
Да, таблица клиентов есть. Но все-равно, надо передавать параметр - дату. Кщд (21.10.09 07:22) [4] был прав. Че то я перемудрил с вопросом. Сори )))
select id_client from clients where id_client not in (select id_client from visit_history where date_visit=:adate)
-
> Германн © (21.10.09 01:36) [1]
Я име ввиду без конструкций типа "for select... suspend" и т.д., присущим процедурам. А то кажется, что я их использую там, где без них можна было б и обойтись
-
если версия ФБ поддерживает execute block, то можно и без ХП..:-)
-
А так нельзя?
SELECT DISTINCT A.ID_CLIENT FROM VISIT_HISTORY A
LEFT JOIN VISIT_HISTORY B ON A.ID_CLIENT=B.ID_CLIENT AND B.VISIT_DATE=<yourdate>
WHERE B.VISIT_DATE IS NULL
-
> palva © (21.10.09 15:29) [9]
не знаю, попробую
-
>palva © (21.10.09 15:29) [9]теперь представим, что в таблице visit_history несколько миллионов записей, что вовсе не удивительно при обширной клиентской базе и высокой частоте посещений... в этих предположениях актуальнее:
select g.id, g.name
from client g
where not exists (select null
from visit_history vh2
where vh2.id_client = g.id
and vh2.visit_date = :dt
)
если посещение гарантированно одно на дату по клиенту, то ещё и уникальный индекс на пару "id_client-visit_date"
-
Здесь ничего не могу ни возразить, ни согласиться. Эффективность запросов для меня темный лес. Возможно, анализатор запросов приведет оба варианта к одной и той же схеме. Хотя мне всегда казалось, что из общих соображений объединение всегда эффективнее многократного подзапроса. А у вас ведь подзапрос будет выполняться для каждой записи, то есть несколько миллионов раз. Кроме того, где-то потерялся DISTINCT.
Если заботиться об эффективности, то лично я делал бы процедуру. Сначала отобрал бы уникальных клиентов, а потом проверял EXISTS. DISTINCT, примененный на раннем этапе помог бы уменьшить число подзапросов. Хотя возможно оптимизатор движка SQL сам бы обнаружил такую возможность.
-
>palva © (22.10.09 09:05) [12] >Возможно, анализатор запросов приведет оба варианта к одной и той же схеме это не так оптимизаторы не настолько умны, чтобы включать или исключать таблицы из запроса)
>объединение всегда эффективнее многократного подзапроса в данном случае, самообъединение таблицы-миллионника гораздо хуже прохода по таблице клиентов с подзапросами, посаженными на индекс
>Кроме того, где-то потерялся DISTINCT в нем нет необходимости
>Если заботиться об эффективности, то лично я делал бы процедуру эффективнее здесь использовать запрос
-
> >Кроме того, где-то потерялся DISTINCT > в нем нет необходимости
А, так у вас отдельная таблица клиентов? Извините, не увидел, что вы анализируете другую задачу.
> >Если заботиться об эффективности, то лично я делал бы процедуру > эффективнее здесь использовать запрос
Ну раз задачи разные, то сравнивать бессмысленно.
-
>palva © (22.10.09 12:05) [14] >А, так у вас отдельная таблица клиентов? Извините, не увидел, что вы анализируете другую задачу. отдельная таблица у автора, что не слишком явно видно из zorik © (20.10.09 23:24) и абсолютно точно в zorik © (21.10.09 09:20) [6]
>Ну раз задачи разные, то сравнивать бессмысленно. да, Ваш вариант никогда не покажет, что клиент не приходил, если его нет в visit_history - так что мы с Вами, действительно, решали разные задачи какую именно решали Вы - пока не ясно)
-
> какую именно решали Вы - пока не ясно)
Задачу, поставленную при открытии ветки.
-
>palva © (22.10.09 19:55) [16] нежелание читать ветку не дает права на советы, ставящие "колом" сервер дальнейшее обсуждение бессмысленно всего
|