Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2014.11.30;
Скачать: [xml.tar.bz2];




Вниз

Как правильно сделать запрос SQL 


KilkennyCat ©   (2014-04-17 20:21) [0]

Пытаюсь исключить из отчета астериска выходные и праздничные дни...
имеем таблицу логов звонков cdr (может достигать сотни тысяч записей), и таблицу "ненужных" дней calendar (около 100 записей ).
подсчитываем звонки за день, на выходя получая три столбца, месяц, день и кол-во звонков.
с джойнами у меня всегда были проблемы, сделал так:
SELECT  MONTH(t.calldate) AS mes,
 DAY(t.calldate) AS dd,
 COUNT(1) AS cc
FROM cdr AS t

WHERE YEAR(t.calldate)=2014
AND NOT EXISTS (SELECT id FROM calendar WHERE DATE(t.calldate) = DATE(id))
GROUP BY MONTH(t.calldate), DAY(t.calldate)


оптимально ли это? или все-таки джойн надо? или еще как?
calldate - тип datatime
id - тип date



junglecat   (2014-04-17 20:26) [1]

FROM cdr AS t
JOIN calendar c on DATE(t.calldate) = DATE(c.id)
WHERE YEAR(t.calldate)=2014
AND c.id IS NULL



KilkennyCat ©   (2014-04-17 20:29) [2]


> junglecat   (17.04.14 20:26) [1]

ага!
спасибо, я увидел свою ошибку, забыл c.id IS NULL :))
полчаса "джойнил" и удивлялся, ошибок нет, выдает все записи...



antonn ©   (2014-04-17 21:10) [3]


> FROM cdr AS t
> JOIN calendar c on DATE(t.calldate) = DATE(c.id)
> WHERE YEAR(t.calldate)=2014
> AND c.id IS NULL

c.id тут вообще может быть null? не left join?



antonn ©   (2014-04-17 21:14) [4]


> не left join?

в смысле "не при left join"



KilkennyCat ©   (2014-04-17 21:17) [5]

ну, про left я помню, добавлен сразу.

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



[ВладОшин] ©   (2014-04-17 21:22) [6]

если в ожидаемом плане написан nested loop, то гонять может

вложенный запрос почти всегда в join исполняется



KilkennyCat ©   (2014-04-17 21:25) [7]

Прочитал, что за nested loop...
"Оператор Nested Loops выполняет логические операции внутреннего соединения, левого внешнего соединения, левого полусоединения и антилевого полусоединения."

ну его нафиг! я помимо выше написанного еще сортировать умею, и хватит с меня :)



Кщд   (2014-04-21 09:59) [8]

[ВладОшин] ©   (17.04.14 21:22) [6]
>вложенный запрос почти всегда в join исполняется
мягко говоря, опрометчивое утверждение)

KilkennyCat ©   (17.04.14 21:25) [7]
в Вашем случае - hash anti-join - самое оно



Кщд   (2014-04-21 10:01) [9]

>junglecat   (17.04.14 20:26) [1]
Вы всегда semi-join переписываете на equi-join?
к тому же, неправильно)



KilkennyCat ©   (2014-04-21 11:24) [10]


> Кщд   (21.04.14 09:59) [8]

спасибо за информацию, сейчас изучу. все слова знакомы, а че в совокупности - понятия не имею, но нутром чувствую - хорошая вещь! :) Ибо, с момента опубликования, запрос стал намного-много запутанней.

Кстати, а существует ли некая методика, а возможно и утилита, для составления, так сказать, параметрических запросов? Т.е. если у меня много условий, которые динамично меняются, то запрос тож динамично меняется.

Просто я дошел уже до состояния, что если мне придется добавить еще одно условие, вызывающее еще одно $zapros .= " AND ".($chtoto?"da":"net")." <=> tabl.eto "; , то оно обязательно будет логически противоречить чему-то давно уже созданному и забытому и я выскочу в окно и убегу.



junglecat   (2014-04-21 11:31) [11]

> Кстати, а существует ли некая методика, а возможно и утилита,
> для составления, так сказать, параметрических запросов?

а какая СУБД?



KilkennyCat ©   (2014-04-21 11:38) [12]

MySql



Кщд   (2014-04-21 12:19) [13]

>KilkennyCat ©   (21.04.14 11:24) [10]
>а возможно и утилита
мне ни один вменяемый инструмент не встречался

>Кстати, а существует ли некая методика
если подлежащие данные объёмны(напр., таблицы-миллионники) и критично время отклика, то методика проста: выделить наиболее часто используемые сочетания параметров и для каждого такого набора написать ОТДЕЛЬНЫЙ, оптимальный для него(набора) sql-запрос



junglecat   (2014-04-21 12:22) [14]

> [12] KilkennyCat ©   (21.04.14 11:38)
> MySql

здесь что-то есть http://dev.mysql.com/downloads/tools/workbench/
есть еще EMS Manager for MySQL, но он платный (либо крякнутый на рутрэкере можно поискать)



Кщд   (2014-04-21 18:52) [15]

>junglecat   (21.04.14 12:22) [14]
"еще одно условие, вызывающее еще одно $zapros .= " AND ".($chtoto?"da":"net")." <=> tabl.eto "; , то оно обязательно будет логически противоречить чему-то давно уже созданному и забытому"

чем поможет EMS?



junglecat   (2014-04-21 19:34) [16]

> чем поможет EMS?

это к вопросу об утилитах, а не противоречиях



KilkennyCat ©   (2014-04-22 09:23) [17]


> для каждого такого набора написать ОТДЕЛЬНЫЙ, оптимальный
> для него(набора) sql-запрос


да, пришлось поступить так. выглядит жутко, но работоспособно, и легче ковыряться, так как не надо в голове просчитывать



Кщд   (2014-04-22 12:13) [18]

>KilkennyCat ©   (22.04.14 09:23) [17]
да, выглядит монструозно, неэстетично, но проще обеспечить должную эффективность и проще поддерживать




Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2014.11.30;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.022 c
15-1398157909     Виктор1985            2014-04-22 13:11  2014.11.30  
Трюки в Delphi


15-1397720688     ТНЕ картман           2014-04-17 11:44  2014.11.30  
голосование))


15-1397723572     й                     2014-04-17 12:32  2014.11.30  
еще 1 задачка


15-1397651154     Дмитрий СС            2014-04-16 16:25  2014.11.30  
Флешка как CD-ROM


15-1398112205     Юрий                  2014-04-22 00:30  2014.11.30  
С днем рождения ! 22 апреля 2014 вторник