Вниз
Скачать: CL | DM;

SQL-запрос посещения   Найти похожие ветки 

← →
zorik ©   (2009-10-20 23:24) [0]

Есть таблица посещений (код клиента, дата визита):

CREATE TABLE VISIT_HISTORY(
 ID_CLIENT  INTEGER NOT NULL,
 VISIT_DATE DATE NOT NULL
);

Можно ли составить запрос тех клиентов, кто не посещал в эти дни. Именно запрос, а не процедуру (процедуру я сделаю). Тоесть надо взять все даты из истории посещений, всех клиентов и вывести тех, кого в который день небыло.

Просто интересно стало есть ли такая возможнось. БД Firebird. Если нет, то сделаю хранимкой, но все же чисто из интереса


← →
Германн ©   (2009-10-21 01:36) [1]

А разве процедура не есть запрос?


← →
Омлет   (2009-10-21 04:20) [2]

Декартово произведение таблицы уникальных клиентов с таблицей уникальных клиентов, оставив только тех, кого в конкретный день не было.


← →
Омлет   (2009-10-21 04:21) [3]

> таблицы уникальных клиентов с таблицей уникальных клиентов

Пардон, пересечение клиентов с датами, конечно.


← →
Кщд   (2009-10-21 07:22) [4]

>Омлет   (21.10.09 04:21) [3]
а если такой даты нет в visit_history?)


← →
Sergey13 ©   (2009-10-21 08:39) [5]

> [0] zorik ©   (20.10.09 23:24)
> Есть таблица посещений

А таблица клиентов есть? Если есть, то NOT EXISTS клиентов в посещениях вернет тебе прогульщиков.


← →
zorik ©   (2009-10-21 09:20) [6]

Да, таблица клиентов есть. Но все-равно, надо передавать параметр - дату. Кщд   (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)


← →
zorik ©   (2009-10-21 09:25) [7]


> Германн ©   (21.10.09 01:36) [1]

Я име ввиду без конструкций типа "for select... suspend" и т.д., присущим процедурам. А то кажется, что я их использую там, где без них можна было б и обойтись


← →
Виталий Панасенко   (2009-10-21 15:00) [8]

если версия ФБ поддерживает execute block, то можно и без ХП..:-)


← →
palva ©   (2009-10-21 15:29) [9]

А так нельзя?

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


← →
zorik ©   (2009-10-21 17:11) [10]


> palva ©   (21.10.09 15:29) [9]

не знаю, попробую


← →
Кщд   (2009-10-22 07:10) [11]

>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"


← →
palva ©   (2009-10-22 09:05) [12]

Здесь ничего не могу ни возразить, ни согласиться. Эффективность запросов для меня темный лес. Возможно, анализатор запросов приведет оба варианта к одной и той же схеме. Хотя мне всегда казалось, что из общих соображений объединение всегда эффективнее многократного подзапроса. А у вас ведь подзапрос будет выполняться для каждой записи, то есть несколько миллионов раз. Кроме того, где-то потерялся DISTINCT.

Если заботиться об эффективности, то лично я делал бы процедуру. Сначала отобрал бы уникальных клиентов, а потом проверял EXISTS. DISTINCT, примененный на раннем этапе помог бы уменьшить число подзапросов. Хотя возможно оптимизатор движка SQL сам бы обнаружил такую возможность.


← →
Кщд   (2009-10-22 09:37) [13]

>palva ©   (22.10.09 09:05) [12]
>Возможно, анализатор запросов приведет оба варианта к одной и той же схеме
это не так
оптимизаторы не настолько умны, чтобы включать или исключать таблицы из запроса)

>объединение всегда эффективнее многократного подзапроса
в данном случае, самообъединение таблицы-миллионника гораздо хуже прохода по таблице клиентов с подзапросами, посаженными на индекс

>Кроме того, где-то потерялся DISTINCT
в нем нет необходимости

>Если заботиться об эффективности, то лично я делал бы процедуру
эффективнее здесь использовать запрос


← →
palva ©   (2009-10-22 12:05) [14]


> >Кроме того, где-то потерялся DISTINCT
> в нем нет необходимости

А, так у вас отдельная таблица клиентов? Извините, не увидел, что вы анализируете другую задачу.

> >Если заботиться об эффективности, то лично я делал бы процедуру
> эффективнее здесь использовать запрос

Ну раз задачи разные, то сравнивать бессмысленно.


← →
Кщд   (2009-10-22 15:01) [15]

>palva ©   (22.10.09 12:05) [14]
>А, так у вас отдельная таблица клиентов? Извините, не увидел, что вы анализируете другую задачу.
отдельная таблица у автора, что не слишком явно видно из zorik ©   (20.10.09 23:24)  и абсолютно точно в zorik ©   (21.10.09 09:20) [6]

>Ну раз задачи разные, то сравнивать бессмысленно.
да, Ваш вариант никогда не покажет, что клиент не приходил, если его нет в visit_history - так что мы с Вами, действительно, решали разные задачи
какую именно решали Вы - пока не ясно)


← →
palva ©   (2009-10-22 19:55) [16]


> какую именно решали Вы - пока не ясно)

Задачу, поставленную при открытии ветки.


← →
Кщд   (2009-10-23 07:51) [17]

>palva ©   (22.10.09 19:55) [16]
нежелание читать ветку не дает права на советы, ставящие "колом" сервер
дальнейшее обсуждение бессмысленно
всего



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.49 MB
Время: 0.005 c
2-1294380604
mefodiy
2011-01-07 09:10
2011.04.03
Разница в представлении данных MySQL.User в D7 и D2010


15-1292349556
Baks
2010-12-14 20:59
2011.04.03
WordPress Drupal Joomla или самому ручками


15-1292534993
Юрий
2010-12-17 00:29
2011.04.03
С днем рождения ! 17 декабря 2010 пятница


1-1251709470
Franzy
2009-08-31 13:04
2011.04.03
Как организовать такую штуку?..


15-1292016597
Юрий
2010-12-11 00:29
2011.04.03
С днем рождения ! 11 декабря 2010 суббота




   Наверх