我需要计算MySQL的中值。我看到了解决方案here。
但是,我不明白它的一部分。提供的解决方案输入代码如下:
SELECT x.val from data x, data y
GROUP BY x.val
HAVING SUM(SIGN(1-SIGN(y.val-x.val))) = (COUNT(*)+1)/2
在原始问题的背景下,data x
和data y
是什么?通常FROM后跟表名。但是,当问题仅涉及一个时,为什么会列出2个表呢?有人可以解释这个解决方案的工作原另外,我不明白这一部分:HAVING SUM(SIGN(1-SIGN(y.val-x.val)))
。
答案 0 :(得分:2)
原始问题的上下文中的数据x和数据y是什么? 通常FROM后跟表名。但是,为什么有2张桌子呢? 当问题只涉及一个时列出?
在原始问题中,data x, data y
将表连接到自身,创建了一个笛卡尔积。原始表有7行,通过将每一行连接到每一行,结果产品为49行。
另外,我不理解这一部分:
HAVING SUM(SIGN(1-SIGN(y.val-x.val)))
。
基本上,此函数为每个值确定有多少值小于被检查的值。然后它将此总数与计数的一半+ 1 ...进行比较,然后选择该值作为中位数。
它通过从比较值(x.val
)中减去值(y.val
)来实现。然后,它使用SIGN
函数将结果转换为-1
,0
或1
。然后它减去这个值,然后再次取SIGN
。因此,如果y.val
值小于要与之比较的x.val
值,则最终结果为1
。例如,假设y
为3
,x
为5
。
3 - 5 = -2
SIGN(-2) = -1
1 - (-1) = 2
SIGN(2) = 1
如果y
为5
,而x
为3
,则最终结果为0
:
5 - 3 = 2
SIGN(2) = 1
1 - 1 = 0
SIGN(0) = 0
总结这些比较的结果给出了一个数字,表示在我们检查的值之前有多少值。然后,它会将此SUM
与COUNT(*) + 1 / 2
进行比较,以找到中间范围......