Помогите с запросом

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Помогите с запросом

Сообщение _sts_ » 20 янв 2008, 22:33

Помогите с запросом - чую, что сделать можно, но моск на этом месте затупил, и никак не соображу:
есть поле с кодом клиентов (FK) и поле даты контакта с клиентом, нужно получить количество тех клиентов, чей код за определенный период мелькнул в таблице 2 и более раз. FB 1.5, ХП и посмотры не подходят, нужен только запрос, возвращающий одно число.

SAMZ
Сообщения: 128
Зарегистрирован: 21 мар 2005, 08:17

Re: Помогите с запросом

Сообщение SAMZ » 21 янв 2008, 06:43

_sts_ писал(а):Помогите с запросом - чую, что сделать можно, но моск на этом месте затупил, и никак не соображу:
есть поле с кодом клиентов (FK) и поле даты контакта с клиентом, нужно получить количество тех клиентов, чей код за определенный период мелькнул в таблице 2 и более раз. FB 1.5, ХП и посмотры не подходят, нужен только запрос, возвращающий одно число.
select T.ClientId. count(*) CNT from Table T
where T.ClientDt between :d1 and :d2
having count(*) > 1

Здесь ClientId - код клиента;
ClientDt- дата контакта

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Re: Помогите с запросом

Сообщение _sts_ » 21 янв 2008, 14:53

SAMZ писал(а):
select T.ClientId. count(*) CNT from Table T
where T.ClientDt between :d1 and :d2
having count(*) > 1

Здесь ClientId - код клиента;
ClientDt- дата контакта
Запрос должен вернуть ОДНО число, а ты намекаешь на группировку (правда GROUP BY где-то потерял :), т.е. нужен каунт от каунта ... вот в чем проблема

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 21 янв 2008, 15:17

Вьё.

Упс, они ж по религиозным соображениям не подходят. Странно это. Ну тогда фетчить этот запрос и загибать пальцы на клиенте. Гы-гы-гы.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 21 янв 2008, 15:26

Он жы сказал "без ХП и вья". Надо бы ответить "не ..би моск, делай ХП".

Вообще, типа так

Код: Выделить всё

select count(c.client_id)
  from clients c
  where c.date between :d1 and :d2 and
        exists (select client_id
                  from clients
                  where date between :d1 and :d2 and
                        client_id = c.client_id
                  group by client_id
                  having count(*) >= 2
               )

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Re: Помогите с запросом

Сообщение stix-s » 21 янв 2008, 15:49

_sts_ писал(а): Запрос должен вернуть ОДНО число, а ты намекаешь на группировку (правда GROUP BY где-то потерял :), т.е. нужен каунт от каунта ... вот в чем проблема
Черт, не подумал и потер

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Сообщение _sts_ » 21 янв 2008, 18:42

Merlin писал(а):Вьё.

Упс, они ж по религиозным соображениям не подходят. Странно это. Ну тогда фетчить этот запрос и загибать пальцы на клиенте. Гы-гы-гы.
Гы-гы-гы - это вы, батенька, зря. Придется пояснять подробней :)
Прога разошлась по городам и весям, а чтобы иметь возможность подстроиться под заморочки каждого юзверя, в ней есть возможность подключения текстового файла с запросом, который (запрос) всегда ограничен диапазоном дат (так надо!) Поэтому ХП тут не катит, хотя согласен, здесь бы - самое оно. Но дистанционно создавать ХП, т.е. изменять структуру базы, я не могу. Не могу и не хочу.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 21 янв 2008, 19:41

_sts_ писал(а): Прога разошлась по городам и весям, а чтобы иметь возможность подстроиться под заморочки каждого юзверя, в ней есть возможность подключения текстового файла с запросом
А подсунуть ей два раза текстовый файлик, первый с креате вью, второй с грант его возжелавшему юзверю, папа не разрешает? :wink:

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Сообщение _sts_ » 22 янв 2008, 17:25

WildSery писал(а):Он жы сказал "без ХП и вья". Надо бы ответить "не ..би моск, делай ХП".

Вообще, типа так

Код: Выделить всё

select count(c.client_id)...

               )
Проверял - неправильно считает.
А как вам такой результат насилия над моском:

Код: Выделить всё

select  count(distinct t.kod) "Контактов>1" from Tab t
where t.kod = any (select t.kod from tab t
where t.dat between '01.01.2006' and '31.12.2009'
group by t.kod
having count(t.kod)>1 )
На тестовой табличке проверял - вроде все правильно (хотя я уже нивчем не уверен :), но берут сомнения насчет производительности - навскидку постоянных клиентов будет тыщ 5 на 500 тыщ строк контактов.
P.S. Спасибо всем за участие :)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 янв 2008, 17:34

_sts_ писал(а):Проверял - неправильно считает.
Полторашки у меня нету, на 2-ке и на 1-це правильно считал. Перепроверять не буду, потому что нихачу.

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Сообщение _sts_ » 22 янв 2008, 17:51

WildSery писал(а):
_sts_ писал(а):Проверял - неправильно считает.
Полторашки у меня нету, на 2-ке и на 1-це правильно считал. Перепроверять не буду, потому что нихачу.
Верю-верю :) но у меня такой вопрос: а зачем дублировать between по дате?
Вдогонку: я понял, в чем дело - у тебя считаются все строки с такими кодами, а мне нужно кол-во клиентов, т.е. distincta не хватает. А так все верно...

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 янв 2008, 18:13

_sts_ писал(а):зачем дублировать between по дате?
Потому что это как бы два разных запроса, и если в кореллирующем подзапросе подхватится фильтр по дате (при наличии соотв. индекса), запрос будет выполняться быстрее.

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Сообщение _sts_ » 22 янв 2008, 18:21

WildSery писал(а):
_sts_ писал(а):зачем дублировать between по дате?
Потому что это как бы два разных запроса, и если в кореллирующем подзапросе подхватится фильтр по дате (при наличии соотв. индекса), запрос будет выполняться быстрее.
Понятно. (Но индекса там нет)
И еще: у Helen Borry видел такой пример:
select sum(count (подзапрос с группировкой) ....), но сколько ни парился, повторить подобную хрень так и не смог. Вообще такое возможно в принципе (т.е. агрегат по полю, кот. строится как рез-т агрегата?)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 янв 2008, 18:48

Нет, двойного агрегата нет нигде. И в стандарте в том числе ;)
Зато с 2-ки можно так:

Код: Выделить всё

select sum(cnt) from
(select id, count(id) as cnt from table group by 1 having count(id)>1) q

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Сообщение _sts_ » 22 янв 2008, 19:08

WildSery писал(а): Зато с 2-ки можно так:

Код: Выделить всё

select sum(cnt) from
(select id, count(id) as cnt from table group by 1 having count(id)>1) q
Круто. Кстати, как там с двойкой - все глюки исправили?
И вообще - ради чего стоит на нее переходить с полторашки?
(Обзоры читал, мне интересно мнение практика)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 янв 2008, 19:48

А что, в полторашке все глюки исправили? :shock:

ЗЫ: Я с 1.0.3 на 2.0.3 наши БД перевожу.

_sts_
Сообщения: 23
Зарегистрирован: 28 авг 2006, 19:38

Сообщение _sts_ » 23 янв 2008, 15:51

WildSery писал(а):А что, в полторашке все глюки исправили?
:)
ЗЫ: Я с 1.0.3 на 2.0.3 наши БД перевожу.
-И это правильно
P.S. Поспал, расслабился, попил пивка - ешкн кот, а твой и мой вариант запроса - этож одно и тоже :)
А вчера реально считал, что они разные ... :?
Вывод - отдыхать надо вовремя. Щас достал бутыль винца домашнего, сбегал за шоколадкой, купил какойто детективчик (а-ля Код да Винчи), пойду устрою праздник моска...
А топик, пожалуй, пора закрыть

Ответить