Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Вебмастеру (http://forum.oszone.net/forumdisplay.php?f=22)
-   -   подсчет уникальных значаний поля в MySQl (http://forum.oszone.net/showthread.php?t=31137)

Vlad Drakula 16-06-2004 22:04 213528

у меня сейчас вот такой запрос:
Код:

 $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 213529

Vlad Drakula
а что xxx делать должна :) ?

Vlad Drakula 16-06-2004 23:09 213530

XXX() - нечто вроде count() только он ститает каличество уникальных значений, а не общее количество полей.

mar 16-06-2004 23:12 213531

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

Vlad Drakula 16-06-2004 23:17 213532

mar
честно говоря я с  JOIN я не разобрался, может ты просветишь меня?

mar 18-06-2004 09:53 213533

в общем виде 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
Тут надо иметь в виду оптимизацию запросов в 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


Vlad Drakula 18-06-2004 19:49 213534

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 213535

:up: :lol: ух ты! верной дорогой идете товарищ-щ-щи!!!

Vlad Drakula 18-06-2004 22:13 213536

к сожалению находятся люди которые утверждают что я ламммер в части баз данных

Prisoner 19-06-2004 00:04 213537

Это не так, можешь приезжать ко мне и я выдам тебе разрешение на плевок в левый глаз за клевету :)

Vlad Drakula 19-06-2004 21:02 213538

а теперь немного дегтя в бочку с медом, в Nodex MySQL 4.0, и возникли проблеммы с тиками запросами, я им мыло уже накатал, что они отстали от жизни :(

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

mar 19-06-2004 22:47 213539

Vlad Drakula
так я тебе и писала, что на MySQL такие штуки не проходят. Проходят на самой (или самых?) последних версиях, но хостеры *(если они разумны :) на них не переходят, равно как и на PHP5, тк там есть несовместимости со старыми версиями и у людей просто работающие приложения обломятся.
Кроме того версии выше четверки - не релизы, поэтому, опять же разумные админы в них пока не играют (можно еще и проблем с безопасностью нахлебаться):
MySQL database server & standard clients:
Цитата:

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)
:)

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

Vlad Drakula 20-06-2004 00:56 213540

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

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

mar 20-06-2004 01:50 213541

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

Vlad Drakula 20-06-2004 07:31 213542

mar
пришлось сделать откат и токазаться от тодсчета уникальных полей.

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

mar 20-06-2004 11:30 213543

Vlad Drakula
Цитата:

а под винду есть нормальная весия?
У нас в фирме несколько человек сидело под виндой и они как-то ставили, кажется, через cygwin. Мне тогда показалось проще и быстрее линукс поставить. Суди сам - *вот, например, довольно подробное руководство. Или вот несколько ссылок. Ну и на сайте разработчиков, конечно

Vlad Drakula 20-06-2004 22:30 213544

mar
а ты устанавливала его под пинду к ПХП, у тебя возникли какиенибуть сложности с их прикручиванием?

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

mar 20-06-2004 22:48 213545

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


Время: 13:05.

Время: 13:05.
© OSzone.net 2001-