带有变量的SQLITE Case Expression避免对表达式进行双重评估

时间:2014-10-07 22:22:23

标签: sql database sqlite

您好我有一个查询,其中表达式将在大多数情况下被评估两次。我只想评估一次。我想分配

CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT)

到一个变量,因此它不会被评估两次。如何在一个SQL查询中执行此操作?

SELECT CASE
           WHEN CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT) > 0 THEN CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT)
           ELSE 0
       END
FROM BUCKETS;

2 个答案:

答案 0 :(得分:6)

您可以在子查询中评估表达式,然后在查询中使用它的名称(expr):

SELECT CASE
           WHEN expr > 0 THEN expr
           ELSE 0
       END
FROM (
  SELECT
    -- add BUCKETS.*, here if you need other BUCKETS fields return to query
    CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT) AS expr 
  FROM BUCKETS
) b

答案 1 :(得分:3)

+1来自@Rimas的答案。

对于它的价值,这是使用Common Table Expression的类似解决方案。

WITH buckets_enhanced AS (
  SELECT CAST(ROUND(VOLUME - ((CAPACITY*1.0)/TIMEFRAME)*(STRFTIME('%s','now') - UPDATED_TIMESTAMP)) AS INT) AS expr 
  FROM BUCKETS
)
SELECT CASE WHEN expr > 0 THEN expr ELSE 0 END 
FROM buckets_enhanced;

学习使用CTE是有用的,因为它们比简单的派生表子查询更强大。
例如,您可以在外部查询中多次使用CTE,如在自联接中一样。