За последние 24 часа нас посетили 18066 программистов и 1606 роботов. Сейчас ищут 938 программистов ...

MySQL - нетривиальная задача

Тема в разделе "MySQL", создана пользователем wolf1980, 9 мар 2013.

  1. wolf1980

    wolf1980 Активный пользователь

    С нами с:
    9 мар 2013
    Сообщения:
    1
    Симпатии:
    0
    Доброго времени суток, уважаемые форумчане!

    Столкнулся с казалось бы простой задачей, однако так и не смог ее решить. Подскажите, пожалуйста, реализацию, заранее спасибо.


    Есть таблица с транзакциями:
    CREATE TABLE `transactions` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `date` INT NOT NULL ,
    `user_id` INT NOT NULL ,
    `amount` INT NOT NULL
    );
    amount может быть положительным и отрицательным.
    Одним запросом найти транзакцию, которая в последний раз уменьшила баланс определенного user_id ниже суммы X.
    Текущий баланс может быть любым.
    amount - это сумма транзакции, баланс - сумма всех транзакций.
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    а как ты пробовал?
     
  3. jenya777777

    jenya777777 Активный пользователь

    С нами с:
    16 мар 2010
    Сообщения:
    562
    Симпатии:
    0
    Тут наверное надо добавить еще один столбец в таблицу, Было-Стало Amount, чтобы видеть что сумма все таки уменьшилась а не увеличилась
     
  4. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    в оракл для подобного есть аналитические функции типа LAG(), LEAD()...
    в мускуле простого решения добиться будет сложно.
     
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    google "mysql running total"
    вот например находится: http://stackoverflow.com/questions/5032360/running-sums-for ... s-in-mysql
    перефразируя на ваши названия:
    Код (Text):
    1.  
    2. select `user_id`, `date`, `amount`,
    3.        (select sum(`amount`)
    4.         from   `transactions` AS t2
    5.         where  t1.`user_id` = t2.`user_id` and t1.`date` >= t2.`date`
    6.         ) as `total`
    7. from `transactions` AS t1
    8. where `user_id`=1
    9. order by `date` desc
    вернет в обратном календарном порядке операции и исходящий остаток для заданного пользователя.
    соответственно если этот запрос завернуть еще в один и добавить WHERE total< X LIMIT 1 то получится нужный ответ.
    медленно, но верно :D