|
|
|
| Здравствуйте!
Устал бороться с самим собой, please help.
Так получилось, что есть 3 таблицы:
1. USERS
uid | username
1 | A
2 | B
3 | C
4 | В
2. MEMBERS (те, кто участвует из USERS)
uid
1
3
4
3. TOP (очки набранные MEMBRES в разных турах)
uid | tour | points
3 | 1 | 15
3 | 2 | 20
3 | 3 | 25
4 | 1 | 5
4 | 2 | 15
4 | 3 | 15
Вопрос:
Как одним запросом вывести таблицу вида:
username | points2
C (uid=3) | 45
D (uid=4) | 30
A (uid=1) | 0
Сортировка по points2 - убывание, а points2 - это сумма 2-х лучших туров из TOP.
При этом в таблице должны быть все MEMBERS, даже если их нет в TOP.
Please, help.
Спасибо.
С уважением,
Александр | |
|
|
|
|
|
|
|
для: Al
(10.02.2005 в 19:59)
| | Хм... в один без вложенных запросов наверное и не получится... сумма из двух лучших результатов всё портит... | |
|
|
|
|
|
|
|
для: cheops
(10.02.2005 в 22:27)
| | Уже согласный и не на один запрос.
Подскажите, пожалуйста, что куда грамотно вложить, чтобы получить искомый результат. | |
|
|
|
|
|
|
|
для: al
(11.02.2005 в 01:12)
| | Честно говоря, что то умнее чем 1 запрос на 1-ого Member мне в голову не приходит. Но вам, наверное, изящней хотелось...
И то при этом сортировку вручную (на PHP) нужно будет делать. Либо через временные таблицы работать - таким образом ручной сортировки можно избежать.
А может быть можно с самого начала эту специальную таблицу формировать? Т.е. не делать анализ большого кол-ва данных. А заполнять таблицу (сумма 2 лучших результатов для каждого участника ) по мере поступления данных и затем просто выводить ее содержимое. | |
|
|
|
|
|
|
|
для: glsv (Дизайнер)
(11.02.2005 в 01:50)
| | Данные меняются скорее всего динамически...
SELECT USERS.uid AS uid,
USERS.username AS username
FROM MEMBERS, USERS
WHERE MEMBERS.uid=USERS.uid
GROUP BY USERS.uid
|
В цикле выполнить данный запрос:
SELECT * FROM TOP
WHERE id =
ORDER BY points DESC
LIMIT 2
|
Здесь нужно будет оператором LIMIT 2, выбрать данные из таблицы TOP, отсортированные в обратном порядке для каждого конкретного MEMBERS - в цикле получить по два результата для каждого из участников и сложить их с одновременным выводом... Всё равно понадобится какая-то постраничная навигация, поэтому в первом запросе скорее всего тоже будет ограничение LIMIT и всё должно работать достотаточно шустро. | |
|
|
|
|
|
|
|
для: cheops
(11.02.2005 в 07:48)
| | Спасибо за наводку.
Буду разбираться. | |
|
|
|
|
автор: cheops (из ННГУ) (11.02.2005 в 19:18) |
|
|
для: Al
(11.02.2005 в 14:16)
| | Если не заладится - пишите... будем дальше разбираться. | |
|
|
|
|
|
|
|
для: cheops
(11.02.2005 в 07:48)
| | Здравствуйте!
Конечно же "не заладилось"... :)
>Здесь нужно будет оператором LIMIT 2, выбрать данные из
>таблицы TOP, отсортированные в обратном порядке для каждого
>конкретного MEMBERS - в цикле получить по два результата для
>каждого из участников и сложить их с одновременным
>выводом...
"сложить их с одновременным выводом... " -
здесь, похоже, мне нужна подсказка поконкретее.
Как это безобразие сложить?
С уважением,
Александр | |
|
|
|
|
|
|
|
для: al
(12.02.2005 в 15:14)
| | Это можно осуществить при помощи следующего кода
<?php
// Устанавливаем соединение с базой данных
include "config.php";
// Формируем и выполняем SQL-запрос
$query = "SELECT * FROM TOP
WHERE id =
ORDER BY points DESC
LIMIT 2";
$tp = mysql_query($query);
if(!$tp) exit(mysql_error());
// Извлекаем записи
$sum = 0;
while($top = mysql_fetch_array($tp))
{
$sum += $top['points'];
}
?>
|
Переменная $sum будет содержать сумму двух максимальных результатов. | |
|
|
|
|
|
|
|
для: cheops
(12.02.2005 в 18:29)
| | cheops, спасибо за квалифицированную помощь. :)
все сработало.
все выводится в таблицу.
только вот где отсортировать вывод MEMBERS в обратном порядке по сумме 2-х тучших туров? | |
|
|
|
|
|
|
|
для: al
(12.02.2005 в 23:37)
| | Здесь это лучше сделать средствами PHP: значение $sum следует поместить в массив, задав в качестве ключа id пользователя
<?php
$arr_aum[$id] = $sum;
?>
|
После чего для обратной сортировки можно использовать функцию arsort()
<?php
$arr_aum = arsort($arr_aum);
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(13.02.2005 в 00:30)
| | Видимо, я что-то не так делаю...
сначала выбираем пользователей
$query="SELECT u.username, m.uid FROM membres m, users u WHERE m.uid=u.username";
$result0=mysql_query($query);
|
пока есть пользователи выбираем для них 2 лучших тура
while($row0=mysql_fetch_array($result0)) {
$query_top_san = "SELECT * FROM top WHERE uid =$row0[uid] ORDER BY points DESC LIMIT 2";
$result_top_san=mysql_query($query_top_san);
|
и суммируем 2 лучших тура в $top_san
if(!$result_top_san) exit(mysql_error());
$top_san = 0;
while($top_temp = mysql_fetch_array($result_top_san))
{
$top_san += $top_temp['points'];
}
|
В результате получаем нужную таблицу, только в произвольной сортировке.
И как применить след. код, ну совсем не знаю.
<?php
$arr_aum[$uid] = $top_san;
?>
<?php
$arr_aum = arsort($arr_aum);
?>
|
cheops, еще раз, пожалуйста, для неталатнтивых программеров... :) | |
|
|
|
|
|
|
|
для: al
(13.02.2005 в 14:16)
| | Хм... так а вроде ничего менять не нужно... может вы выложите сам скрипт и скажете в какой строке трудности? | |
|
|
|
|
|
|
|
для: al
(13.02.2005 в 14:16)
| | трудности в сортировке.
вопрос в том, как в итоге все отсортировать по сумме 2-х лучших туров по убыванию?
сейчас, я так понял, что у меня сортируется по первому SELECT
$query="SELECT u.username, m.uid FROM membres m, users u WHERE m.uid=u.username";
$result0=mysql_query($query);
|
а вот куда вставить код, чтобы была правильная сортировка - не понятно
<?php
$arr_aum[$uid] = $top_san;
?>
<?php
$arr_aum = arsort($arr_aum);
?>
|
| |
|
|
|
|
|
|
|
для: al
(13.02.2005 в 17:51)
| | Первую строку следует вставить непосредственно после данного цикла while
<?php
if(!$result_top_san) exit(mysql_error());
$top_san = 0;
while($top_temp = mysql_fetch_array($result_top_san))
{
$top_san += $top_temp['points'];
}
// Помещаем результат в массив $arr_aum
$arr_aum[$uid] = $top_san;
?>
|
а вторую после всех циклов, т.е. когда приложение выйдет из самого первого цикла. | |
|
|
|