简体   繁体   English

MySQL 在 Limit 内使用 Case 语句识别中位数

[英]MySQL Identify median using Case statement within Limit

I'm trying to write a query within mySQL that will return the medium number of Northern Latitudes (LAT_N) rounded to 4 decimal places.我正在尝试在 mySQL 中编写一个查询,该查询将返回四舍五入到小数点后 4 位的北纬中位数 (LAT_N)。 Can anyone tell me where I'm going wrong?谁能告诉我哪里出错了? I'm not necessarily looking for the perfect solution, just want to understand why I can't use the case function within the limit, or whether I'm even writing the case statement correctly.我不一定要寻找完美的解决方案,只是想了解为什么我不能在限制范围内使用案例 function,或者我是否正确地编写了案例语句。

Select ROUND(Lat_N, 4)
FROM Station
ORDER BY Lat_N
LIMIT CASE 
        WHEN COUNT(LAT_N) % 2 = 0 
          THEN 2 
        ELSE 1 
    END
Offset FLOOR(COUNT(LAT_N)/2);

According to MySQL Reference Manual :根据 MySQL 参考手册

The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT 子句可用于限制 SELECT 语句返回的行数。 LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants... LIMIT 接受一个或两个数字 arguments,它们都必须是非负 integer 常量...

So, you can use dynamic sql query as the following:因此,您可以使用动态 sql 查询,如下所示:

Set @lmt = (Select CASE WHEN COUNT(LAT_N) % 2 = 0 THEN 2 ELSE 1 END From Station);
Set @ofst = (Select FLOOR(COUNT(LAT_N)/2) From Station);
Set @qr = CONCAT('Select ROUND(Lat_N, 4) AS LAT_N FROM Station ORDER BY Lat_N LIMIT ', @lmt, ' OFFSET ', @ofst , ';');
PREPARE STMT FROM @qr;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;

Another approach, you may use the RWO_NUMBER() function to simulate the limit and offset functionality as the following:另一种方法,您可以使用RWO_NUMBER() function 来模拟限制和偏移功能,如下所示:

Set @lmt = (Select CASE WHEN COUNT(LAT_N) % 2 = 0 THEN 2 ELSE 1 END From Station);
Set @ofst = (Select FLOOR(COUNT(LAT_N)/2) From Station);
Select D.LAT_N
From
(
  Select ROUND(Lat_N, 4) AS LAT_N, 
         ROW_NUMBER() Over (Order By LAT_N) AS RN
  From Station
) D
Where D.RN Between @ofst+1 And @ofst+@lmt

Check this demo .检查这个演示

Also, you may check this post for more information about how to get the median using SQL.此外,您可以查看这篇文章以获取有关如何使用 SQL 获取中位数的更多信息。

In

SELECT ROUND(Lat_N, 4)
FROM Station
ORDER BY Lat_N

you read all rows.您阅读了所有行。 There is no aggregation taking place.没有发生聚合。 You select and order all rows.您 select 并订购所有行。 Now in your LIMIT clause you suddenly talk about the aggregation value COUNT(LAT_N) , but your result set doesn't contain this value, as you never aggregated your data.现在,在您的LIMIT子句中,您突然谈论聚合值COUNT(LAT_N) ,但您的结果集不包含此值,因为您从未聚合过数据。

Usually you can evaluate aggregation values in a subquery:通常您可以在子查询中评估聚合值:

LIMIT CASE WHEN (SELECT COUNT(LAT_N) % 2 FROM Station) = 0 THEN ...

but MySQL does not suppport subqueries in the LIMIT clause yet.但是 MySQL 还不支持LIMIT子句中的子查询。

Your query doesn't seem to deal with an even amount of rows either.您的查询似乎也没有处理偶数行。

Here is the query I'd use instead:这是我要改用的查询:

SELECT ROUND(AVG(Lat_N), 4)
FROM
(
  SELECT
    Lat_N,
    ROW_NUMBER() OVER (ORDER BY Lat_N) AS rn,
    COUNT(*) OVER () AS cnt
  FROM Station
) x
WHERE rn BETWEEN FLOOR((cnt + 1) / 2) AND CEIL((cnt + 1) / 2);

Demo: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=8fb0f7386d0ccb2a386e82b642b21830演示: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=8fb0f7386d0ccb2a386e82b642b21830

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM