Mysql Groupby и проблема Orderby - PullRequest
1 голос
/ 01 апреля 2010

Вот моя структура данных

альтернативный текст http://luvboy.co.cc/images/db.JPG

когда я пытаюсь это sql

select rec_id, customer_id, dc_number, balance
from payments
where customer_id='IHS050018'
group by dc_number
order by rec_id desc;

что-то не так, idk

Мне нужно

rec_id  customer_id   dc_number   balance

2        IHS050018      DC3        -1
3        IHS050018      52         600 

Я хочу, чтобы последний баланс клиента соответствовал dc_number?

Thanx

Ответы [ 3 ]

1 голос
/ 01 апреля 2010

По сути, есть два способа получить это

select p.rec_id, p.customer_id, p.dc_number, p.balance
from payments p
where p.rec_id IN (
    select s.rec_id
    from payments s
    where s.customer_id='IHS050018' and s.dc_number = p.dc_number
    order by s.rec_id desc
    limit 1);

Также, если вы хотите получить последний баланс для каждого покупателя, которого вы можете сделать

select p.rec_id, p.customer_id, p.dc_number, p.balance
from payments p
where p.rec_id IN (
    select s.rec_id
    from payments s
    where s.customer_id=p.customer_id and s.dc_number = p.dc_number
    order by s.rec_id desc
    limit 1);

То, что я считаю по существу другим способомиспользует тот факт, что select rec_id с order by desc и limit 1 эквивалентно выбору max (rec_id) с соответствующей группой by, в полном объеме:

select p.rec_id, p.customer_id, p.dc_number, p.balance
from payments p
where p.rec_id IN (
    select max(s.rec_id)
    from payments s
    group by s.customer_id, s.dc_number
    );

Это должно быть быстрее (если вы хотите последний балансдля каждого клиента), поскольку max обычно дешевле, чем sort (с индексами он может быть одинаковым).

Кроме того, при такой записи подзапрос не коррелируется (его не нужно запускать для каждой строкивнешний запрос), что означает, что он будет выполнен только один раз, и весь запрос может быть переписан как объединение.

Также обратите внимание, что было бы полезно написать его как коррелированный запрос (добавив, где s.customer_id = p.customer_id и s.dc_number = p.dc_number во внутреннем запросе) в зависимости от селективности внешнего запроса,

Это может улучшить производительность, если вы ищете последний баланс только в одну или несколько строк.

0 голосов
/ 01 апреля 2010

Я не думаю, что есть хороший способ сделать это в SQL без оконных функций (например, в Postgres 8.4 ). Возможно, вам придется перебирать набор данных в вашем коде и таким образом получать последние остатки.

0 голосов
/ 01 апреля 2010

ЗАКАЗ приходит раньше, чем ГРУППА:

select rec_id, customer_id, dc_number, balance
from payments
where customer_id='IHS050018'
order by rec_id desc
group by dc_number
...