子查询返回多个值

时间:2019-09-05 11:21:44

标签: sql sql-server

我有一个要求,我需要找到三个值的中位数,即获取中间值,而不是这些值的最小值和/或最大值。当我按照下面的[提供静态值]运行此代码补丁时,得到了所需的结果。在循环中为动态值运行这批代码会导致问题。

我尝试针对返回错误的值分别运行此逻辑,并且工作正常,给了我预期的结果

DECLARE @MAX FLOAT
DECLARE @final_weight FLOAT
DECLARE @TempMedianTable TABLE (rownum int, weights Float)

INSERT INTO @TempMedianTable 
SELECT ROW_NUMBER() Over (Order By v ASC) ,v 
FROM (Values (10514.7),(1820.03),(884.52)) AS Value(v)

SELECT * FROM @TempMedianTable

SET @MAX = (SELECT max(weights) FROM @TempMedianTable)
PRINT @MAX

SET @final_weight = CEILING(IIF(@MAX > 1000, (SELECT weights FROM @TempMedianTable WHERE rownum = 2), @MAX ))
PRINT @final_weight

运行动态值时,子查询返回以下错误:

  

子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。

SET @final_weight = CEILING(IIF(@MAX > 1000, (SELECT weights FROM @TempMedianTable WHERE rownum = 2), @MAX ))

2 个答案:

答案 0 :(得分:2)

如果您想要三个值的中位数,为什么不这样做呢?

SELECT v.Value
FROM (Values (10514.7),(1820.03),(884.52)) AS Value(v)
ORDER BY Value.v
OFFSET 1 ROW FETCH FIRST 1 ROW ONLY;

答案 1 :(得分:1)

在您的特定示例中,只有3个字词-因此您只需选择中间值即可。但这不是实际计算中位数的方法。

中位数的计算方式如下:集合从最小到最大排序。如果项的数量为奇数,则中值为中间项。如果项数为偶数,则中位数为两个中间值之和除以2。

如果您具有SQL Server 2016或更高版本,则可以使用PERCENTILE_CONT(0.5)查找真实的中位数。无论术语数量是偶数还是奇数,这都将适用。

https://docs.microsoft.com/en-us/sql/t-sql/functions/percentile-disc-transact-sql?view=sql-server-2016

SELECT DISTINCT PERCENTILE_CONT (0.5) WITHIN GROUP (ORDER BY [weights]) 
         OVER (PARTITION BY 1) AS [median]
  FROM @TempMedianTable

在这种情况下,由于PERCENTILE_CONT需要一个分区,因此我为所有值都分配了相同的partition = 1。

对于您的示例数据,这将产生输出:

median
1820.03