Выборка по разным валютам

Тема в разделе "Базы данных", создана пользователем Waki, 27 июн 2013.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Waki

    Waki Постоялец

    Регистр.:
    14 ноя 2012
    Сообщения:
    64
    Симпатии:
    21
    Имеется таблица такого вида:
    Код:
    +----+--------+----------+----------+
    | id | title  | currency | price    |
    +----+--------+---------------------+
    | 1  | title1 | RUB      | 650000   |
    | 2  | title2 | $        |  53000   |
    | 3  | title3 | $        | 190000   |
    | 4  | title4 | $        |  65000   |
    | 5  | title5 | RUB      | 550000   |
    +----+--------+----------+----------+
    
    Как видно присутствует два вида валюты, сложность в том если на сайте делать поиск по цене (к примеру не выше 50000), то в выборку не войдут те которые забиты рублями.
    Как можно средствами мускла сделать подобную выборку, с перерасчетом?

    Пробовал таким запросом:
    Код:
    SELECT id, title, currency, price, IF(currency='$', price, round(price/30)) new_price FROM products;
     
    на выходе:
    +----+-----------+----------+--------+-----------+
    | id | title     | currency | price  | new_price |
    +----+-----------+----------+--------+-----------+
    | 1  | title1    | RUB      | 650000 |     21667 |
    | 2  | title2    | $        |  53000 |     53000 |
    | 3  | title3    | $        | 190000 |    190000 |
    | 4  | title4    | $        |  65000 |     65000 |
    | 5  | title5    | RUB      | 550000 |     18333 |
    +----+-----------+----------+--------+-----------+
    
    Но тут не получается использовать в WHERE этот new_price.
    Выбирать все и отсортировать на пхп думаю как-то ресурсозатратно или я ошибаюсь?
    Вариант с добавлением поля валюты в поиск не подходит, т.к. получается что будет искать только по одной из валют.
     
  2. Darkmind

    Darkmind SNMP maniac

    Регистр.:
    31 май 2006
    Сообщения:
    183
    Симпатии:
    75
    Вообще беда в том, что нарушена нормализация базы. Одна колонка содержит значения по сути разного типа. Было бы удобнее унифицировать значения валюты для хранения, а поле `price` хранило бы предпочтительную валюту для отображения.

    Есть кривое решение в лоб:
    Код:
    SELECT `id`,`title`,`currency`,
    IF(`currency`='$', `price`, round(`price`/30)) AS `cena`
    FROM `products`
    WHERE ( IF(`currency`='$', `price`, round(`price`/30)) < 50000 )
    Более правильное решение - создать представление и использовать потом его:
    Код:
    CREATE VIEW products_mod
    AS
    SELECT `id`,`title`,
    IF(`currency`='$', `price`, round(`price`/30)) AS `cena`
    FROM `products`
     
    SELECT * FROM `products_mod` WHERE `cena` < 50000
    
    Ну или писать хранимку, но с представлением как-то проще, на мой взгляд.
     
    Waki нравится это.
  3. Waki

    Waki Постоялец

    Регистр.:
    14 ноя 2012
    Сообщения:
    64
    Симпатии:
    21
    Darkmind, отличное решение с представлением, спасибо.
    Один вопрос, как в дальнейшем обновлять запрос для представления? Или нужно удалить и создать снова? Имею ввиду если доллар станет дороже или дешевле.
     
  4. Darkmind

    Darkmind SNMP maniac

    Регистр.:
    31 май 2006
    Сообщения:
    183
    Симпатии:
    75
    Select к представлению пишется как для обычной таблицы, если в представление нужно добавить новые данные - делаем DROP и CREATE VIEW заново.
     
    Waki нравится это.
  5. NoName999

    NoName999 Создатель

    Регистр.:
    27 июн 2013
    Сообщения:
    14
    Симпатии:
    5
    По хорошему нужно вообще избавиться от "магического числа" значения курса в запросе. Либо как было сказано выше, забивать в отдельную таблицу курс и просто в SELECT добавить еще и получение этого числа. Так реально более гибкая система будет и не надо будет каждый раз обновлять код представления. А если пойти дальше, то вообще получать с какого-нибудь web-сервиса актуальный банковский курс (при желании задав маржу в расчеты).
     
    Waki нравится это.
Статус темы:
Закрыта.