2010-02-14 2 views
1

У меня есть SQL-запрос, который объединяет историческую информацию о ценах. Это не особенно чисто и, вероятно, может быть оптимизировано очень много. Одна из причин этого заключается в том, что я использую подзапрос, чтобы захватить «предыдущее» значение цены через подзапрос и назначить его псевдониму «last_value». В идеале я хотел бы использовать этот псевдоним в предложении WHERE, вместо того, чтобы повторно выполнять поиск.Условная логика в псевдонимах SQL

Я понимаю, почему это невозможно (SQL-запросы анализируются справа налево, с использованием псевдонимов, применяемых до передачи данных обратно, насколько я понимаю). Я просто хотел опубликовать здесь, чтобы спросить, можно ли сделать что-то подобное, используя альтернативные способы.

В частности, мне бы очень хотелось рассчитать процентное различие между p.value (текущее значение) и last_value (последним значением) через SQL, а не делать это на уровне приложения.

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

Я использую MySQL.

$sql = "SELECT 
       t.*, 
       p.value, 
       p.timestamp, 
       (SELECT 
        value 
       FROM 
        prices 
       WHERE 
        prices.id = p.id AND 
        prices.country=':country' AND 
        prices.timestamp < p.timestamp 
       ORDER BY 
        prices.timestamp DESC 
       LIMIT 1) AS last_value 
      FROM 
       prices AS p, 
       titles AS t 
      WHERE 
       t.row_id = p.id AND 
       p.country = ':country' AND 
       p.current = 1 AND 
       (SELECT 
        value 
       FROM 
        prices 
       WHERE 
        prices.id = p.id AND 
        prices.country=':country' AND 
        prices.timestamp < p.timestamp 
       ORDER BY 
        prices.timestamp DESC 
       LIMIT 1) IS NOT NULL 
      ORDER BY 
       p.timestamp DESC 
      LIMIT :offset, :limit"; 
+0

Какая СУБД? Ответ для каждого будет совсем другим. – Aaronaught

+0

Извините, должен был указать. MySQL. – ndg

ответ

2

Я никогда не использовал MySQL, но в SQL Server Я хотел бы сделать что-то вроде этого:

SELECT (last.value - current.value)/last.value AS percentage 
FROM (SELECT ....) AS last 
INNER JOIN (SELECT ...) AS current 
ON last.PK = current.PK 

Он может по-прежнему работать в MySQL, так как это в значительной степени Standad SQL-92, я считаю. Вот ссылка на документы MySQL об этом: http://dev.mysql.com/doc/refman/5.0/en/unnamed-views.html

0

У Александра была правильная идея (к сожалению, я не могу проголосовать за вас, потому что с тех пор я зарегистрировался в соответствующей учетной записи Stackoverflow). SQL I закончил использование:

SELECT 
        current.*, 
        last.value AS last_value 
       FROM 
        (SELECT 
         t.*, 
         p.id AS p_id, 
         p.value, 
         p.timestamp 
        FROM 
         prices AS p, 
         titles AS t 
        WHERE 
         t.row_id = p.id AND 
         p.country = ':country' AND 
         p.current = 1 
        ) current 
       INNER JOIN 
        (SELECT 
         prices.* 
        FROM 
         prices 
        WHERE 
         prices.country = ':country' AND 
         prices.current = 0 
        ORDER BY 
         prices.timestamp DESC) last 
        ON 
         last.id = current.p_id AND 
         last.timestamp < current.timestamp 
       GROUP BY 
        current.row_id 
       ORDER BY 
        current.timestamp DESC, 
        current.name ASC 
       LIMIT :offset, :limit 
Смежные вопросы