![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
SQL по выводу постоянных пользователей [FireBird 1.5]
DelphiN! © (2007-10-19 12:45:00)Есть таблицы CASEBASE и USERS
с полями
таблица: CASEBASE
Поля: UserName_ Time_
Содержит: список всех операций пользователей
UserName_ - имя пользователя
Time_ - время начала операции
-----------
Таблица: Users
Поля: UserName_ RegistredTime_
Содержит: Время регистрации каждого пользователя
UserName_ имя пользователя
RegistredTime_ время регистрации
------------------
Необходимо вывести список пользователей,которые сделали более 2х операций за период времени, при этом время регистрации пользователей, попадающих под условие должно быть более 30ти дней от времени операции
Вот что у меня получилось :
SELECT UserName_,
count (distinct EXTRACT(DAY FROM Time_)||'.'||EXTRACT(MONTH FROM Time_)||'.'||EXTRACT(YEAR FROM Time_))
FROM CaseBase WHERE (TIME_ > '15.08.2007')and(TIME_ < '15.09.2007')and (exists (select REGISTREDTIME_ from users where (casebase.UserName_ = users.UserName_)and((casebase.time_ - users.registredtime_)>30)))
GROUP BY cardno_
having count (distinct EXTRACT(DAY FROM Time_)||'.'||EXTRACT(MONTH FROM Time_)||'.'||EXTRACT(YEAR FROM Time_)) > 2
ORDER BY 2
Однако данный запрос выводит пустоту, где у меня ошибка?
Johnmen (2007-10-22 11:36:00) [1]
> DelphiN! (22.10.07 09:48) [22]
> Индексы следующие :
1. Не видна уникальность/неуникальность индексов.
2. Где индекс на USERS.cardno_?
3. Попробуй вынести проверку разности времен из условия соединения в WHERE.
Sergey13 (2007-10-22 10:18:00) [2]> [20] DelphiN! (20.10.07 13:37)
Все таки план выполнения покажи.
DelphiN! (2007-10-22 09:48:00) [3]
> Johnmen © (20.10.07 22:52) [21]
Выполняется более 15ти минут
Индексы следующие :
CASEBASE
___________________________________________________
0 CASEBASE_IDX2 CARDNO_ 0 1 Ascending 0,000158881477545946836
___________________________________________________
1 RDB$PRIMARY2 ID_ 1 1 Ascending 0
___________________________________________________
0 CASEBASE_IDX1 TIME_ 0 1 Ascending 0,0000102923013400868513
___________________________________________________
USERS
___________________________________________________
1 RDB$PRIMARY17 ID_ 1 1 Ascending 0,000213858002098277211
___________________________________________________
0 USERS_IDX1 REGISTREDTIME_ 0 1 Ascending 0,000213995284866541624
___________________________________________________
Johnmen (2007-10-20 22:52:00) [4]
SELECT CB.cardno_, COUNT (*)
FROM CaseBase CB
JOIN Users U ON (CB.cardno_ = U.cardno_) AND ((CB.time_ - U.registredtime_) > 30 )
WHERE CB.time_ BETWEEN '15.08.2007' AND '15.10.2007'
GROUP BY CB.cardno_
HAVING COUNT(*) > 2
ORDER BY 2
Какие есть индексы на
CB.cardno_
U.cardno_
CB.time_
?
DelphiN! (2007-10-20 13:37:00) [5]
> Sergey13 © (19.10.07 16:32) [19]
Открываю IbExpert, открываю базу, жму F12, вставляю в окно редактора это :
SELECT cardno_,
count (*)
FROM CaseBase, Users
WHERE (TIME_ > '15.08.2007')and(TIME_ < '15.10.2007')and (casebase.cardno_ = users.cardno_) and (casebase.time_ - users.registredtime_)>30
GROUP BY cardno_
having count (*) > 2
ORDER BY 2
Жму F9
И долго жду :-)
Sergey13 (2007-10-19 16:32:00) [6]> [18] DelphiN! (19.10.07 16:17)
> Мне кажется что данный запрос выполняется долго так как
В моем варианте [10] Sergey13 © (19.10.07 14:17) вроде не должно бы быть так. Поэтому и предложил тебе его. Может ты его неправильно переделал?
Давай сюда последний свой вариант и план его вполнения.
DelphiN! (2007-10-19 16:17:00) [7]
> Sergey13 © (19.10.07 15:15) [17]
нет, также долго ...
Мне кажется что данный запрос выполняется долго так как
в строках
(casebase.UserName_ = users.UserName_) and (casebase.time_ - users.registredtime_)
стоит выборка из поля Users столько раз, сколько записей подходят под условие
(CASEBASE.TIME_ > '15.08.2007')and(CASEBASE.TIME_ < '15.10.2007')
это приходится делать, так как в таблице CASEBASE нет поля User.RegistredTime_
Sergey13 (2007-10-19 15:15:00) [8]> [15] DelphiN! (19.10.07 15:09)
Если count (distinct EXTRACT(DAY FROM Time_)||'.'||EXTRACT(MONTH FROM Time_)||'.'||EXTRACT(YEAR FROM Time_))
заменить на count(*) скорость приемлемая?
Маша Шрайбер (2007-10-19 15:13:00) [9]>> DelphiN! (19.10.07 14:39) [13]
>> Что такое ХП?
Хранимая процедура. Вы разве еще не освоили www.ibase.ru ???
DelphiN! (2007-10-19 15:09:00) [10]
> Sergey13 © (19.10.07 14:44) [14]
Индексы по полю Time в таблицах Users и CaseBase имеются
В таблице CASEBASE сейчас 100 000 записей в данный момент
Каждый месяц прибавляется примерно по столько же
В таблице Users - 5 000 записей в данный момент
Каждый месяц прибавляется примерно по столько же
Sergey13 (2007-10-19 14:44:00) [11]> [13] DelphiN! (19.10.07 14:39)
Много ли записей в таблице CaseBase и есть ли индекс по Time_?
DelphiN! (2007-10-19 14:39:00) [12]
> Sergey13 © (19.10.07 14:17) [10]
> Попробуй в таком варианте
Данный запрос также выполняется очень долго ... (
> Маша Шрайбер © (19.10.07 14:34) [12]
Что такое ХП?
Как это реализовать?
Маша Шрайбер (2007-10-19 14:34:00) [13]>> DelphiN! (19.10.07 14:23) [11]
Тогда м.б. стоит реализовать данную логику в ХП. Это позволит гибко оптимизировать выполнение сего [0] действа, в первую очередь по времени.
DelphiN! (2007-10-19 14:23:00) [14]
> Маша Шрайбер © (19.10.07 14:16) [9]
> А это принципиально, чтобы одним запросом?
Данный запрос должна выполнять не только специальная программа для него, он также должен легко выполняться в любом SQL редакторе(например IbExpert).
Sergey13 (2007-10-19 14:17:00) [15]> [8] DelphiN! (19.10.07 14:09)
Попробуй в таком варианте
SELECT UserName_,
count (distinct EXTRACT(DAY FROM Time_)||'.'||EXTRACT(MONTH FROM Time_)||'.'||EXTRACT(YEAR FROM Time_))
FROM CaseBase, Users
WHERE (TIME_ > '15.08.2007')and(TIME_ < '15.10.2007')and (casebase.UserName_ = users.UserName_) and (casebase.time_ - users.registredtime_)>30
GROUP BY UserName_
having count (distinct EXTRACT(DAY FROM Time_)||'.'||EXTRACT(MONTH FROM Time_)||'.'||EXTRACT(YEAR FROM Time_)) > 2
ORDER BY 2
Маша Шрайбер (2007-10-19 14:16:00) [16]чуть быстрее select 0 from вместо select REGISTREDTIME_ from
>> DelphiN! © (19.10.07 12:45)
А это принципиально, чтобы одним запросом?
DelphiN! (2007-10-19 14:09:00) [17]
> Sergey13 © (19.10.07 13:50) [7]
> Какой диалект, в Time_ реально время есть?
Dialect 1
Да, в Time_ есть дата и время
Sergey13 (2007-10-19 13:50:00) [18]> [6] DelphiN! (19.10.07 13:28)
Какой диалект, в Time_ реально время есть?
DelphiN! (2007-10-19 13:28:00) [19]
> Sergey13 © (19.10.07 13:19) [4]
Не уточнил, по условию нужно считать только колличество дней, в которые производились операции.
Тоесть если в один день выполнилось 4 операции, а на второй день еще 3, нужно подсчитать их как 2 операции(2 уникальных дня,в которые производились операции)
Правильный_Вася (2007-10-19 13:25:00) [20]индексы по дате есть?