请求解析用于计算中位数的T-SQL查询及相关疑问
拆解T-SQL中位数查询的逻辑
咱们一步步来捋清楚这段求中位数的T-SQL代码(你提供的代码缺了关键的FETCH部分,我补上了,这是原逻辑里必不可少的环节):
DECLARE @c BIGINT = (SELECT COUNT(*) FROM [dbo].[Items_per_Order]) GO SELECT AVG(1.0 * [total_de_itens]) AS MEDIAN FROM ( SELECT [total_de_itens] FROM [dbo].[Items_per_Order] ORDER BY [total_de_itens] OFFSET (@c - 1) / 2 ROWS FETCH NEXT 1 + (1 - @c % 2) ROWS ONLY ) AS sub
第一步:统计总行数
DECLARE @c BIGINT = (SELECT COUNT(*) FROM [dbo].[Items_per_Order])
这行代码先把Items_per_Order表的总行数存到变量@c里。中位数的计算核心是找到有序数据的中间位置,所以必须先明确总共有多少条数据,这是整个逻辑的基础前提。
第二步:子查询定位中间数据
子查询里的几个关键操作咱们逐个说:
ORDER BY [total_de_itens]:先把total_de_itens列从小到大排序,中位数的计算必须基于有序数据集,这一步是核心准备工作,没它就找不到中间位置。OFFSET (@c - 1) / 2 ROWS:这里用整数除法计算要跳过的行数,举两个例子就懂了:- 如果总条数是奇数(比如5条):
(5-1)/2=2,也就是跳过前2行,直接定位到第3行——这就是奇数个数据的中间值位置。 - 如果总条数是偶数(比如4条):
(4-1)/2=1(整数除法会舍去小数),跳过前1行,定位到第2行,这是偶数个数据的第一个中间值位置。
- 如果总条数是奇数(比如5条):
FETCH NEXT 1 + (1 - @c % 2) ROWS ONLY:这部分控制要取多少行,同样分奇偶情况:- 奇数条数据时:
@c%2=1,计算后是1+(1-1)=1,只取1行,就是中间那唯一的中位数。 - 偶数条数据时:
@c%2=0,计算后是1+(1-0)=2,取中间的两行,后续要算它们的平均值。
- 奇数条数据时:
第三步:计算最终中位数
SELECT AVG(1.0 * [total_de_itens]) AS MEDIAN
外层用AVG函数计算平均值:
- 如果是奇数条数据,子查询只返回1行,
AVG就是这行的值,也就是咱们要的中位数。 - 如果是偶数条数据,子查询返回中间两行,
AVG会算出这两个数的平均值,这也是偶数个数据时中位数的标准定义。
内容的提问来源于stack exchange,提问作者André Neiva Liboreiro
相关产品推荐
相关产品推荐

