2010-02-14 6 views
1

J'ai une requête SQL qui regroupe des informations historiques sur les prix. Ce n'est pas particulièrement propre et pourrait probablement être optimisé beaucoup. Une raison à cela est que j'utilise une sous-requête pour saisir la valeur de prix 'précédente' via une sous-requête et l'affecter à l'alias 'last_value'. Idéalement, j'aimerais pouvoir utiliser cet alias dans la clause WHERE des requêtes, plutôt que d'avoir à refaire la recherche.Logique conditionnelle sur les alias SQL

Je comprends pourquoi cela n'est pas possible (les requêtes SQL sont analysées de droite à gauche, avec des alias appliqués avant que les données ne soient renvoyées, si je comprends bien). Je voulais juste poster ici pour demander si quelque chose comme ça peut être rendu possible en utilisant d'autres moyens. Plus précisément, j'aimerais calculer la différence en pourcentage entre p.value (la valeur actuelle) et last_value (la dernière valeur) via SQL, plutôt que de devoir le faire au niveau de la couche d'application. J'ai considéré considérer le pourcentage de différence comme une colonne séparée dans la table elle-même, mais cela semble un peu en arrière (étant donné que la logique impliquée est triviale, et la seule pierre d'achoppement est l'utilisation de l'alias).

J'utilise 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

Quel SGBD? La réponse pour chacun sera très différente. – Aaronaught

+0

Désolé, aurait dû préciser. MySQL – ndg

Répondre

2

Je ne ai utilisé MySQL, mais dans SQL Server que je ferais quelque chose comme ceci:

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

Il pourrait encore travailler dans MySQL, comme il est à peu près standad SQL-92, je crois. Voici un lien vers MySQL docs sur ce point: http://dev.mysql.com/doc/refman/5.0/en/unnamed-views.html

0

Alexander avait la bonne idée (je ne peux malheureusement pas vous en voter parce que je l'ai signé depuis avec un compte Stackoverflow approprié). Le SQL que je fini par utiliser:

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 
Questions connexes