在mySQL中使用CASE功能的奇怪工作

时间:2017-04-09 17:19:00

标签: mysql case

我希望通过这个问题了解mySQL的工作原理。 所以我想得到某一列中元素的中位数。查看问题here。我一直在尝试做的是获取变量@ct中的总行数,并派生一个表,其中所有行都被编号并按相关列的值排序。 然后,我只查询其行满足条件的列的平均值,并且条件取决于@ct是奇数还是偶数。以下是该工作代码。

SET @ct := (select count(*) from STATION); %This stores the number of rows
SET @rowNum :=0; %This will be used to save row number for each row.


SELECT AVG(q.LAT_N) 

FROM (SELECT LAT_N,(@rowNum:=@rowNum+1) n FROM STATION ORDER BY LAT_N) AS q

WHERE q.n = (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE @ct/2 OR (@ct+1)/2 END)

奇怪的是,当在最后一行而不是使用OR来对两个值进行排序时,我会这样做,

 WHERE q.n = (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE (@ct/2,(@ct+1)/2) END)

OR

WHERE q.n IN (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE (@ct/2,(@ct+1)/2) END)

我一直收到语法错误Operand should contain 1 column(s) 知道发生了什么事吗?我错过了一些基本的语法规则吗? 我也尝试使用IF函数。

2 个答案:

答案 0 :(得分:1)

您的方法存在多个问题。

您的第一个查询对偶数计数不起作用,因为@ct/2 OR (@ct+1)/2将始终返回1TRUE)。因此,您将始终获得最低价值。

您的第二个WHERE条件不起作用,因为CASE表达式不能返回多个列。你可以做的是使用BETWEEN条件:

WHERE q.n BETWEEN (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE @ct/2 END)
              AND (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE (@ct+1)/2 END)

WHERE 
    CASE WHEN @ct%2
        THEN q.n = (@ct+1)/2
        ELSE q.n BETWEEN @ct/2 AND (@ct+1)/2
    END

但是(@ct+1)/2对于偶数计数是错误的,应该是@ct/2+1

但你甚至不需要CASE表达。你也可以使用

WHERE q.n BETWEEN @ct/2
              AND @ct/2+1

答案 1 :(得分:0)

这不是你问题的答案。但我认为这是解决问题的方法。

SET @ct := (select count(*) from STATION);
SET @rowNum :=0; 
SET @start := floor((@ct+1)/2);
SET @end := ceil((@ct+1)/2);

SELECT AVG(q.LAT_N) 

FROM (SELECT LAT_N,(@rowNum:=@rowNum+1) n FROM STATION ORDER BY LAT_N) AS q

WHERE q.n in(@start,@end);

拜托,试试吧。