Войти

Показать полную графическую версию : подсчет уникальных значаний поля в MySQl


Vlad Drakula
16-06-2004, 22:04
у меня сейчас вот такой запрос:

 $QueryStringList = mysql_query('SELECT IF( LOCATE("?", l.QueryString) = 0, l.QueryString, LEFT(l.QueryString, LOCATE("?", l.QueryString)  - 1) ) as QueryString,
                                 count(*) as Count,
                                 sum(l.ByteSent) as AllByteSent,
                                 l.Result,
                                 sum(l.ByteSent) / '.$MaxByte['Max'].' as prb,
                                 count(*) / '.$MaxCount['Max'].' as prc
                            FROM logs as l, brouser as b
                           WHERE l.Date >= "'.$StartDate.'"
                             AND l.Date <= "'.$EndDate.'"
                             AND ( '.$r.' )
                             AND b.id=l.Brouser
                        GROUP BY l.QueryString, l.Result
                        '.$sort.';') or print mysql_error();

а хочется нечто вот такое:

 $QueryStringList = mysql_query('SELECT IF( LOCATE("?", l.QueryString) = 0, l.QueryString, LEFT(l.QueryString, LOCATE("?", l.QueryString)  - 1) ) as QueryString,
                                 count(*) as Count,
                                 ХХХ(IP) as nIp,
                                 sum(l.ByteSent) as AllByteSent,
                                 l.Result,
                                 sum(l.ByteSent) / '.$MaxByte['Max'].' as prb,
                                 count(*) / '.$MaxCount['Max'].' as prc
                            FROM logs as l, brouser as b
                           WHERE l.Date >= "'.$StartDate.'"
                             AND l.Date <= "'.$EndDate.'"
                             AND ( '.$r.' )
                             AND b.id=l.Brouser
                        GROUP BY l.QueryString, l.Result
                        '.$sort.';') or print mysql_error();

только вот не знаю что поставить всместо XXX?

сдается что такого нельзя осуществить :(

mar
16-06-2004, 22:57
Vlad Drakula
а что xxx делать должна :) ?

Vlad Drakula
16-06-2004, 23:09
XXX() - нечто вроде count() только он ститает каличество уникальных значений, а не общее количество полей.

mar
16-06-2004, 23:12
count(IP) .... group by IP и JOIN это к основному запросу
(в postgres-е можно было бы запрос в запросе сделать :( )

Vlad Drakula
16-06-2004, 23:17
mar
честно говоря я с  JOIN я не разобрался, может ты просветишь меня?

mar
18-06-2004, 09:53
в общем виде JOIN - аналог выбора из двух таблиц, связанных между собой по каким-то полям (полю)
SELECT a.id, b.qq FROM a_table a, b_table_b WHERE a.column1=b.column2;
можно записать, как *
SELECT a.id, b.qq FROM a_table a
JOIN b_table_b ON a.column1=b.column2;
(или, по крайней мере в постгресе можно еще сказать USING c, если с - поле связи, одинаково названное в обоих таблицах.

Дальше начинается самое интересное, когда можно присоединять не все данные одной, или другой таблицы
LEFT JOIN, RIGHT JOIN
Тут надо иметь в виду оптимизацию запросов (http://dev.mysql.com/doc/mysql/ru/LEFT_JOIN_optimisation.html) в mysql
Дальше еще интересней, но, честно говоря, по-моему, это не должно работать : в постгресе (и, по-моему вообще по SQL-стандартам, поправьте кто-нибудь, если не так :) можно на связываемые таблицы наложить разные (в том числе и по order и group by условия), например: (кусок работающего примера из postgres-а)
SELECT ............
FROM participant_view p
JOIN
* *(
* * *SELECT
* * * *dst, src,
* * * *0- sum(amount) AS amount,
* *currency
* * *FROM trlog
* * *WHERE
* * stamp <= '%s' AND
status = %d GROUP BY dst, currency, src
* *) t ON (t.dst = p.id and t.src > 0)
JOIN currency c ON (c.id=t.currency)
......
ORDER BY p.name

Вот. Собственно, когда я писала - имела в виду последний случай, но, боюсь, он в MySQL смысла не имеет :(
В твоем случае, скорее, для MYSQL можно использовать UNION (http://dev.mysql.com/doc/mysql/ru/UNION.html)

Vlad Drakula
18-06-2004, 19:49
mar
ох... много раз у меня баз аданных умирала...
но всетаки я написал...
вот что уменя получилось:

 $LogList = mysql_query('SELECT l.Date,
                                count(*) as Count,
                                sum(l.ByteSent) as AllByteSent,
                                sum(l.ByteSent) / '.$MaxByte['Max'].' as prb,
                                count(*) / '.$MaxCount['Max'].' as prc,
                                l2.C as C
                           FROM logs as l
                      LEFT JOIN ( SELECT l3.Date,
                                         count(*) as C
                                    FROM ( SELECT Date
                                             FROM logs
                                         GROUP BY Date, FromIp) as l3
                        GROUP BY l3.Date) as l2 ON l.Date = l2.Date
                          WHERE l.Date >= "'.$StartDate.'"
                            AND l.Date <= "'.$EndDate.'"
                       GROUP BY l.Date, l2.Date
                       '.$sort.';') or print mysql_error();


но работает все это очень медленно :(

буду оптимизировать.

Добавлено:

в итоге было:

 $MaxByte = mysql_fetch_array(mysql_query('SELECT sum(ByteSent) as Max
                                             FROM logs
                                            WHERE Date >= "'.$StartDate.'"
                                              AND Date <= "'.$EndDate.'"
                                         GROUP BY Date
                                         ORDER BY Max DESC;'));

 $MaxCount = mysql_fetch_array(mysql_query('SELECT count(*) as Max
                                             FROM logs
                                            WHERE Date >= "'.$StartDate.'"
                                              AND Date <= "'.$EndDate.'"
                                         GROUP BY Date
                                         ORDER BY Max DESC;'));


 $LogList = mysql_query('SELECT l.Date,

                                count(*) as Count,

                                sum(l.ByteSent) as AllByteSent,

                                sum(l.ByteSent) / '.$MaxByte['Max'].' as prb,

                                count(*) / '.$MaxCount['Max'].' as prc,

                                l2.C as C

                           FROM logs as l

                      LEFT JOIN ( SELECT l3.Date,

                                         count(*) as C

                                    FROM ( SELECT Date

                                             FROM logs

                                         GROUP BY Date, FromIp) as l3

                        GROUP BY l3.Date) as l2 ON l.Date = l2.Date

                          WHERE l.Date >= "'.$StartDate.'"

                            AND l.Date <= "'.$EndDate.'"

                       GROUP BY l.Date, l2.Date

                       '.$sort.';') or print mysql_error();


стало:


 $LogList = mysql_query('SELECT l1.*,
                                l1.Count / m.Max_Count as prc,
                                l1.AllByteSent / m.Max_Byte as prb,
                                l2.C
                           FROM ( SELECT Date,
                                         count(*) as Count,
                                         sum(ByteSent) as AllByteSent
                                    FROM logs
                                   WHERE Date >= "'.$StartDate.'"
                                     AND Date <= "'.$EndDate.'"
                                GROUP BY Date
                                         '.$sort.') as l1,
                                ( SELECT l3.Date,
                                         count(*) as C
                                    FROM ( SELECT Date
                                             FROM logs
                                         GROUP BY Date, FromIp) as l3
                                GROUP BY l3.Date) as l2,
                                ( SELECT MAX(m1.Max_Byte) as Max_Byte,
                                         MAX(m2.Max_Count) as Max_Count
     FROM ( SELECT Date,
                                                       sum(ByteSent) as Max_Byte
                                                  FROM logs
                                              GROUP BY Date
                                              ORDER BY Max_Byte DESC) as m1
                                    LEFT JOIN ( SELECT Date,
                                                       count(*) as Max_Count
                                                  FROM logs
                                                 WHERE Date >= "'.$StartDate.'"
                                                   AND Date <= "'.$EndDate.'"
                                              GROUP BY Date
                                              ORDER BY Max_Count DESC) as m2
                                         USING( Date )) as m
                          WHERE l1.Date=l2.Date;') or print mysql_error();

mar
18-06-2004, 21:45
:up: :lol: ух ты! верной дорогой идете товарищ-щ-щи!!!

Vlad Drakula
18-06-2004, 22:13
к сожалению находятся люди которые утверждают что я ламммер в части баз данных

Prisoner
19-06-2004, 00:04
Это не так, можешь приезжать ко мне и я выдам тебе разрешение на плевок в левый глаз за клевету :)

Vlad Drakula
19-06-2004, 21:02
а теперь немного дегтя в бочку с медом, в Nodex MySQL 4.0, и возникли проблеммы с тиками запросами, я им мыло уже накатал, что они отстали от жизни :(

еще могу скзать что производительность сервера в нодексе сравнима с производительностью моего локал хоста, а иногда и выше, что очень приятно!

mar
19-06-2004, 22:47
Vlad Drakula
так я тебе и писала, что на MySQL такие штуки не проходят. Проходят на самой (или самых?) последних версиях, но хостеры *(если они разумны :) на них не переходят, равно как и на PHP5, тк там есть несовместимости со старыми версиями и у людей просто работающие приложения обломятся.
Кроме того версии выше четверки - не релизы, поэтому, опять же разумные админы в них пока не играют (можно еще и проблем с безопасностью нахлебаться):
MySQL database server & standard clients: (http://dev.mysql.com/downloads/index.html)
MySQL 4.0 -- Production release (recommended)
MySQL 4.1 -- Alpha release (use this for new development)
MySQL 5.0 -- Development tree (use this for previewing and testing new features)
:)

Исправлено: mar, 22:48 19-06-2004

Vlad Drakula
20-06-2004, 00:56
mar
жалко... очень жалко...
но я наднюсь я всетаки смогу осуществить нечто такое на MySQL 4.0 я сейчас скачиваю 4.0.20с, буду пытаться все перевести под нее, если не получится то в пимечании напишу - требуется MySQL 4.1.

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

mar
20-06-2004, 01:50
переходи на постгрес, - на том же нодексе он доступен (равно, как и ssh для работы с ним, если я правильно поняла)
Получишь кучу возможностей и не в альфа-версии ;)
(в том числе и замечательные операторы для отладки-проверки эффективности: EXPLAIN / EXPLAIN ANALYZE с просмотром времени, идущего на выполнение запроса )

Vlad Drakula
20-06-2004, 07:31
mar
пришлось сделать откат и токазаться от тодсчета уникальных полей.

mar
а под винду есть нормальная весия?
ведь встаки дома я разрабатываю под виндой.

mar
20-06-2004, 11:30
Vlad Drakula
а под винду есть нормальная весия?
У нас в фирме несколько человек сидело под виндой и они как-то ставили, кажется, через cygwin. Мне тогда показалось проще и быстрее линукс поставить. Суди сам - *вот (http://ssy.mccinet.ru/pg_inst_w98.html), например, довольно подробное руководство. Или вот (phpclub.ru/?m=faq&s=97) несколько ссылок. Ну и на сайте разработчиков (http://www.postgresql.org), конечно

Vlad Drakula
20-06-2004, 22:30
mar
а ты устанавливала его под пинду к ПХП, у тебя возникли какиенибуть сложности с их прикручиванием?

например MySQL ставишь и все работает само сабой, я даже на горячую менял версии под виндой.

mar
20-06-2004, 22:48
я постгрес под винды не ставила (только видела, что у людей стоит.) С PHP проблем быть не должно, но в нем должны быть соответствующие функции для работы с постгресом (как функции для работы с MySQL - для работы с ним). Ну это phpinfo() проверяется.




© OSzone.net 2001-2012