SQL别名的条件逻辑

时间:2010-02-14 16:32:42

标签: sql logic boolean alias

我有一个SQL查询,它将历史价格信息拼凑在一起。它不是特别干净,可能会进行大量优化。其中一个原因是我使用子查询通过子查询获取“先前”价格值并将其分配给别名“last_value”。理想情况下,我希望能够在查询WHERE子句中使用此别名,而不必重新执行查找。

我理解为什么这是不可能的(根据我的理解,SQL数据从右到左解析,在数据传回之前应用了别名)。我只是想在这里发帖询问是否可以使用其他方法使这样的事情成为可能。

具体来说,我非常想通过SQL计算p.value(当前值)和last_value(最后一个值)之间的百分比差异,而不是必须在应用程序层进行。

我已经考虑将百分比差异作为一个单独的列存储在表本身中,但这看起来有点倒退(假设所涉及的逻辑是微不足道的,唯一的绊脚石就是使用别名)。

我正在使用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";

2 个答案:

答案 0 :(得分: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,因为它相当于标准的SQL-92。这是MySQL文档的链接: http://dev.mysql.com/doc/refman/5.0/en/unnamed-views.html

答案 1 :(得分:0)

亚历山大有正确的想法(遗憾的是我不能投票给你,因为我已经注册了适当的Stackoverflow帐户)。我最终使用的SQL:

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