【问题标题】:simplify SQL statement by using CTE使用 CTE 简化 SQL 语句
【发布时间】:2012-03-01 04:02:04
【问题描述】:

我有如下查询:

SELECT A.a, A.b, B.c,
(CASE WHEN ... THEN ... ELSE ... END) AS CalculatedValue,
B.d
FROM    dbo.TableA A INNER JOIN
        dbo.TableB B ON (...)
WHERE (CASE WHEN ... THEN ... ELSE ... END) BETWEEN @DayStart AND @DayEnd
GROUP BY A.a, (CASE WHEN ... THEN ... ELSE ... END), B.c

为避免多次重复完全相同的表达式:(CASE WHEN ... THEN ... ELSE ... END) 我想定义一个 CTE 并在 select、where 中使用表达式查询此类表CalculatedValue

不幸的是,这不起作用,因为在创建 CTE 时选择需要已经包含 group by

有没有其他方法可以避免重复CASE WHEN... 这么多次?

【问题讨论】:

    标签: sql sql-server-2008 common-table-expression cross-apply


    【解决方案1】:

    使用CROSS APPLY,可用于定义别名字段,然后引用:

    SELECT A.a, 
           A.b, 
           B.c,
           CalculatedValue,
           B.d
    FROM    
           dbo.TableA A 
    INNER JOIN
            dbo.TableB B 
            ON (...)
    CROSS APPLY 
            (SELECT (CASE WHEN ... THEN ... ELSE ... END)) CxA(CalculatedValue)
    WHERE CalculatedValue BETWEEN @DayStart AND @DayEnd
    GROUP BY A.a, CalculatedValue, B.c
    

    CxA 只是一个别名,您可以随意命名。

    【讨论】:

    • 感谢 JNK,这解决了问题,执行时间相同但代码比以前更干净,+1 和绿旗 ;-)
    • 乐于助人!我自己最近才知道这一点,它让很多事情变得更简单。
    • 将通用逻辑封装在表值函数中会变得非常有趣。查询最终可能会读取 table CROSS APPLY udf1 CROSS APPLY udf2 CROSS APPLY udf3 并且所有“正常”的 SQL 都被隐藏起来了!
    • 实际上再次检查性能我看到重复代码但没有 CROSS APPLY 我的原始查询需要大约 22 秒,并且语法更好更整洁, CROSS APPLY 需要大约 1:22 秒,开销为1 分钟获得更好的语法 :( 我不能这样使用它...
    • @DavidePiras - 它仍然应该只计算一次。如果是性能问题,请打开一个新 Q,如果我们知道查询的表结构和详细信息,我们可能会提供帮助。我想不出任何理由将其放入CROSS APPLY 会导致性能问题。
    【解决方案2】:

    对于以上内容,我认为您可以只做两层 CTE。第一个将为所有计算,第二个将从第一个 CTE 中选择并根据计算值进行过滤。最终查询将加入第二层 CTE。

    只是一个想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多