如何避免 SELECT、GROUP BY 和 ORDER BY 中的函数重复 SQL

How to avoid function repetition in SELECT, GROUP BY, and ORDER BY in SQL

我正在编写一个统计查询,其中值在 SELECTGROUP BYORDER BY 中重复。必须重复相同的值使得难以读取和修改查询。

如何避免在下面的查询中重复 FLOOR(COALESCE(LEN(Body), 0) / 100) 3-4 次。

SELECT FLOOR(COALESCE(LEN(Body), 0) / 100) * 100 as BodyLengthStart,
    (FLOOR(COALESCE(LEN(Body), 0) / 100) + 1) * 100 - 1 as BodyLengthEnd,
    COUNT(*) as MessageCount
FROM [Message]
GROUP BY FLOOR(COALESCE(LEN(Body), 0) / 100)
ORDER BY FLOOR(COALESCE(LEN(Body), 0) / 100)

查询的输出是消息的数量与它们有多少个字符相结合。

BodyLengthStart BodyLengthEnd MessageCount
0 99 130
100 199 76
200 299 36

您可以使用常见的 table 表达式:

WITH cte AS 
(
SELECT FLOOR(COALESCE(LEN(Body), 0) / 100) * 100 as BodyLengthStart,
    (FLOOR(COALESCE(LEN(Body), 0) / 100) + 1) * 100 - 1 as BodyLengthEnd
FROM [Message]
)
SELECT BodyLengthStart,BodyLengthEnd,COUNT(*)
FROM cte
GROUP BY BodyLengthStart,BodyLengthEnd

使用子select:

SELECT  BodyLengthStart,
        BodyLengthEnd,
        COUNT(*)
FROM (SELECT FLOOR(COALESCE(LEN(Body), 0) / 100) * 100 as BodyLengthStart,
            (FLOOR(COALESCE(LEN(Body), 0) / 100) + 1) * 100 - 1 as BodyLengthEnd
        FROM [Message]) as a
GROUP BY BodyLengthStart,
         BodyLengthEnd

可以在FROM之后定义一个SELECT;这样,您就可以事先详细说明您的数据。

一个选项可能是 CTE(通用 Table 表达式),大致如下:

WITH x AS
(
    SELECT FLOOR(COALESCE(LEN(Body), 0) / 100) AS BodyLength
    FROM [Message]
)
SELECT BodyLength * 100 AS BodyLengthStart,
       (BodyLength + 1) * 100 - 1 AS BodyLengthEnd,
       COUNT(*) as MessageCount
FROM x
GROUP BY BodyLength
ORDER BY BodyLength 

附带说明 - 如果在此之前的语句没有以分号 (;) 结尾,则这将无法按预期工作。

使用交叉应用

SELECT  BodyLengthStart,
        BodyLengthEnd,
        COUNT(*)
FROM  [Message]
CROSS APPLY (
   VALUES 
      (FLOOR(COALESCE(LEN(Body), 0) / 100)) 
   ) a1(v)
CROSS APPLY (
   VALUES
      (v * 100, (v + 1) * 100 - 1)
   ) a2(BodyLengthStart, BodyLengthEnd)
GROUP BY BodyLengthStart,
         BodyLengthEnd