|
автор: новичек (10.07.2005 в 12:06) |
|
| есть выборка
<?
$qry_sbalance = "select sum(exchange) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now()";
$sbalance = db_get_id($qry_sbalance);
?>
|
так вот, задача состоит в том, чтобы выбирать количество записей равное какому-то числу, к примеру 10.
тоесть если есть записей меньше 10, то нечего не выбирается, если есть больше 10, к примеру 12, то выбирается 10, а 2 игнорируется, если есть к примеру 24, то выбирается 20, а 4 игнорируется.
надеюсь ясно обьянил что нужно.
подскажите пожалуйста. | |
|
|
|
|
|
|
|
для: новичек
(10.07.2005 в 12:06)
| | Для этого в конце запроса используется инструкция LIMIT - запрос вида
SLECT * FROM tbl LIMIT 10
|
выберет 10 записей
SLECT * FROM tbl LIMIT 20
|
выберет 20 записей
SLECT * FROM tbl LIMIT 10, 10
|
выберет 10 записей, начиная с 10
SLECT * FROM tbl LIMIT 20, 10
|
выберет 10 записей начиная с 20
В том конетексте, который требуется вам - потребуется сначала опеределить число записей, а затем динамически при помощи PHP формировать значения параметров для инструкции LIMIT. | |
|
|
|
|
автор: новичек (10.07.2005 в 13:03) |
|
|
для: cheops
(10.07.2005 в 12:43)
| | насчет LIMIT я знаю
а как опеределить число записей, а затем динамически при помощи PHP сформировать значения параметров для инструкции LIMIT ? | |
|
|
|
|
|
|
|
для: новичек
(10.07.2005 в 13:03)
| | Для этого необходимо выполнить запрос, который подсчитает число строк в вашем будующем запросе
<?
$qry_sbalance = "select count(*) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now()";
$sbalance = db_get_id($qry_sbalance);
if(!$sbalance) exit(mysql_error());
$total = mysql_result($sbalance,0);
?>
|
$total будет содержать число записей, в зависимости от полученного числа принимайте решение, если $total<10 вообще не запрашивайте данные, если больше 10, но меньше 20 значение в LIMIT выставьте в 10
<?
if($total > 10 && $total < 20) $num = 10;
$qry_sbalance = "select sum(exchange) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now() LIMIT $num";
$sbalance = db_get_id($qry_sbalance);
?>
|
Только логику округления до 10 нужно продумать... | |
|
|
|
|
автор: новичек (10.07.2005 в 21:31) |
|
|
для: cheops
(10.07.2005 в 15:54)
| | спасибо.
все это конечно хорошо если строк до 20, а если их будет больше ?
не очень хочется к примеру напихивать так
if($total > 20 && $total < 30) $num = 20;
//
if($total > 30 && $total < 40) $num = 30;
и т.д.
|
тоесть их может быть неограниченное количество, как можно сделать чтобы автоматом определяла кратность и правильность определения $num ?
к тому же это не обязательно должно быть 10, это для примера, а так это такая же переменная которая вводится пользователем при регистрации и она может быть любой, начиная от 5 и выше. | |
|
|
|
|
автор: новичек (10.07.2005 в 23:08) |
|
|
для: новичек
(10.07.2005 в 21:31)
| | и еще такой момент
есть поле p_id, тоесть могут быть записи с одинаковыми данными
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now()
|
но с разными по p_id, тоесть получается что надо как то сгруппировать по p_id и все что проходит по условию ссумировать поле sum(exchange)
может все это так сложно сделать, может посоветуете какой другой вариант выборки ??? | |
|
|
|
|
|
|
|
для: новичек
(10.07.2005 в 23:08)
| | А вы не могли бы привести пример того, что нужно получить, т.е. что на входе, а что должно быть на выходе? | |
|
|
|
|
|
|
|
для: новичек
(10.07.2005 в 21:31)
| | Ну эта задача решаемая, нужно разделить $total на 10, округлить результат в меньшую сторону при помощи функции floor() и опять умножить на 10.
<?php
$num = $total/10;
$num = floor($num);
$num = $num*10;
?>
|
| |
|
|
|
|
автор: новичек (11.07.2005 в 01:54) |
|
|
для: cheops
(11.07.2005 в 01:00)
| | спасибо с этим ясно.
а насчет того что на входе и что должно быть на выходе.
суть такая, пользователь написал статью, ее порядковый номер заносится в p_id, каждый день создается таблица в которую заносится сколько оригинальных человек эту статью просмотрело, за каждого просмотревшего заносится премиальный бонус в поле exchange, к примеру за 10 дней суммируются все бонусы по этой статье и выводятся в графу в акке, он может эти бонусы потратить (на что не столь важно), если он их тратит, то упдатится графа pmt_type по этим дням и в дальнейшем эти дни не учитываются. но он может их не тратить а накапливать.
но вот к примеру он написал сегодня статью и завтра статью, и через 2 дня еще одну, через 11 дней, после написания первой статьи период начисления истекает по этим первым обеим статьям, значит должны подсчитатся бонусы по ним обеим, а по третьей статье период начисления (10 дней) еще не истек, значит она учитываться не должна.
статья может висеть 30, 60, 90,120 дней, потом она удаляется (в дальнейшем может срок будет увеличин), значит каждые 10 дней происходит обсчет бонусов.
если к примеру одна статья провисела 20, другая 33, и пользователь не тратил бонусу, то должна вывестись сумма за первую за 20 дней + сумма за вторую за 30 дней.
надеюсь саму суть подсчета обьяснил.
вот как это лучше реализовать ? | |
|
|
|
|
|
|
|
для: новичек
(11.07.2005 в 01:54)
| | Здесь удобно воспользоваться группировкой по полю p_id при помощи конструкции GROUP BY
select sum(exchange) from lines
where uid=$user_id and status='$STATUS_ENUM_ENABLE' and
pmt_type<>'$TRANS_ENUM_SPEND'
GROUP BY p_id
|
| |
|
|
|
|
автор: новичек (11.07.2005 в 02:35) |
|
|
для: cheops
(11.07.2005 в 02:19)
| | если не трудно напишите пожалуйста как все это будет выглядить вместе, вся выборка. | |
|
|
|
|
|
|
|
для: новичек
(11.07.2005 в 02:35)
| | Мне несколько трудно это сделать, так как я не совсем понимаю логику запроса, например строку "and date<now()", ведь дата казалось бы всегда будет меншье текущей? | |
|
|
|
|
автор: новичек (11.07.2005 в 13:05) |
|
|
для: cheops
(11.07.2005 в 12:59)
| | почему она будет всегда меньше текущей ?
если эта таблица образована сегодня то дата будет равна сегоднишней дате, а значит это значение не учитывается. | |
|
|
|
|
|
|
|
для: новичек
(11.07.2005 в 13:05)
| | У меня то нет структуры таблицы :))), а сам я предпочитаю использовать тип DATETIME и прибегаю к DATE только в специальных случаях... | |
|
|
|
|
автор: новичек (11.07.2005 в 13:25) |
|
|
для: cheops
(11.07.2005 в 13:12)
| | ну получается что это должно выглядить как то так ?
$qry_sbalance = "select count(*) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now()
GROUP BY p_id ";
$sbalance = db_get_id($qry_sbalance);
if(!$sbalance) exit(mysql_error());
$total = mysql_result($sbalance,0);
$num = $total/10;
$num = floor($num);
$num = $num*10;
$qry_sbalance = "select sum(exchange) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now() LIMIT $num";
$sbalance = db_get_id($qry_sbalance);
?>
|
только я не пойму тогда, как будут суммироваться все суммы выбраных груп ? | |
|
|
|
|
|
|
|
для: новичек
(11.07.2005 в 13:25)
| | Нет, имеется ввиду
<?
$qry_sbalance = "select count(*) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now()
";
$sbalance = db_get_id($qry_sbalance);
if(!$sbalance) exit(mysql_error());
$total = mysql_result($sbalance,0);
$num = $total/10;
$num = floor($num);
$num = $num*10;
$qry_sbalance = "select sum(exchange) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now() GROUP BY p_id LIMIT $num";
$sbalance = db_get_id($qry_sbalance);
?>
|
| |
|
|
|
|
автор: новичек (11.07.2005 в 14:06) |
|
|
для: cheops
(11.07.2005 в 13:35)
| | ок
спасибо, щас попробую | |
|
|
|
|
автор: новичек (11.07.2005 в 22:48) |
|
|
для: новичек
(11.07.2005 в 14:06)
| | уважаемый ХЕОПС, вроде все работает, но есть один баг которого я не могу понять, запрос совершенно не реагирует на LIMIT, пробовал вместо переменной подставлять конкретное число, не помогает.
тоесть если есть к примеру в группе 12 записей, то она так и считает 12, а не 10 как должно быть, такое впечатление что LIMIT вообще не прописан.
в чем может быть дело ? | |
|
|
|
|
автор: новичек (11.07.2005 в 23:47) |
|
|
для: новичек
(11.07.2005 в 22:48)
| | и еще, как при таком запросе вытащить значение p_id , что бы знать какие группы она суммирует ? | |
|
|
|
|
|
|
|
для: новичек
(11.07.2005 в 23:47)
| | А прямо через запятую, MySQL здесь нарушает стандарт SQL и позволяет помещать рядом с агрегатными функциями имена столбцов, по которым происходит группировка
<?php
$qry_sbalance = "select p_id, sum(exchange) from lines where
uid=$user_id and status='$STATUS_ENUM_ENABLE'
and pmt_type<>'$TRANS_ENUM_SPEND' and date<now() GROUP BY p_id LIMIT $num";
?>
|
| |
|
|
|
|
автор: новичек (12.07.2005 в 00:56) |
|
|
для: cheops
(12.07.2005 в 00:48)
| | MySQL 4.1.8-max
я так прописал, но как мне вывести чтобы она была видимой переменной, тоесть к примеру
$pp_id = $что-то[p_id'];
что нужно подставить вместо что-то ?
или как то по другому она выводится ? | |
|
|
|
|
|
|
|
для: новичек
(12.07.2005 в 00:56)
| | Можно воспользоваться следующим кодом
<?php
$sbalance = mysql_query($qry_sbalance);
if(!$sbalance) exit(mysql_error());
while($total = mysql_fetch_array($sbalance))
{
echo $total['p_id']."<br>";
}
?>
|
| |
|
|
|
|
автор: новичек (12.07.2005 в 01:12) |
|
|
для: cheops
(12.07.2005 в 01:02)
| | спасибо попробую, а насчет LIMITа никаких пожеланий не будет ? | |
|
|
|
|
|
|
|
для: новичек
(11.07.2005 в 22:48)
| | Хм... вообще-то не должно бы... а версия MySQL какая? | |
|
|
|
|
автор: новичек (12.07.2005 в 20:39) |
|
|
для: cheops
(12.07.2005 в 00:49)
| | и еще такая проблема
предположим, что в поле pmt_id 2 группы 9 и 10, в поле exchange у этих групп разные значения, у одной 0.1 у другой 0.15, общее число $num = 40 к примеру, из 40 10 это группы 9, а 30 это группы 10, по идеи она должна вывести общую сумму 2 групп 1+4.5=5.5, но она выводит сумму только одной группы. а если к примеру в 9 группе не 10 а 15 таблиц, а так как $num=40, то она и выводит общию сумму 1.5, а вторая група просто игнорируется.
как это все исправить, чтобы правильно работало ???
помогите, горю !!! | |
|
|
|
|
автор: новичек (12.07.2005 в 21:10) |
|
|
для: новичек
(12.07.2005 в 20:39)
| | вообще может подскажите какое то более простое решение задачи.
задача такая.
основные поля exchange и p_id
есть несколько групп, группа определяется по значению в поле p_id
у каждой группы есть свое числовое значение в поле exchange
количество рядов у каждой группы может быть разное.
задача
сделать выборку по каждой группе с суммой всех значений из поля exchange по количеству рядов кратным 10.
сложить все полученные значения от всех групп.
вывести результат. | |
|
|
|
|
|
|
|
для: новичек
(12.07.2005 в 21:10)
| | Вот без кратных 10 эта задача решается при помощи запроса
SELECT p_id, sum(exchange)
FROM lines
GROUP BY p_id WITH ROLLUP;
|
WITH ROLLUP - выводит в конце сумму по группам (правда введён в MySQL, начиная только с 4.1.1). | |
|
|
|