使用 row_number() 获取一组记录中的中间行

问题描述 投票:0回答:2

之前我提出了一个问题,询问如何获取一组记录中的第一行,该问题得到了很好的解决。遗憾的是,我的客户稍后改变了他的请求,所以这次我请求您帮助找到一组记录中的中间行,即具有以下内容:

温度ID 选角ID 温度日期时间 温度值
1421294 1073513 2021-01-07 11:53:00.000 1648
1421295 1073513 2021-01-07 11:54:00.000 1698
1421296 1073513 2021-01-07 11:57:00.000 1699

我必须取 1421295 条记录,而偶数要么是中间 + 1,要么是中间 - 1

所以从这个查询开始,返回1421294记录就清楚了

SELECT * 
    FROM (
        SELECT 
            CastingID, TemperatureValue, TemperatureDateTime
            , ROW_NUMBER() OVER (PARTITION BY CastingID ORDER BY CastingID) RN
        FROM Production.Temperatures
        where YEAR(TemperatureDateTime) = 2021 and PhaseID = 250
    ) A
    WHERE RN = 1 and year(A.TemperatureDateTime) = 2021

我能得到我想要的结果还是我必须改变我的方法?

sql sql-server median row-number
2个回答
2
投票

编辑:更新为使用 cte。 Edit2:更新为使用联接而不是子选择来处理多个castIds

既然

ROW_NUMBER()
会给我们一组连续的值,为什么不找到
MAX(RN)
,除以 2,然后舍入呢?如果
MAX(RN)
是奇数,您将得到真正的中位数,如果是偶数,您将得到四舍五入。可能有一种更干净的方法可以做到这一点,但类似这样:

  WITH cte AS (
        SELECT 
            temperatureID 
            ,castingID
            ,temperatureValue
            ,ROW_NUMBER() OVER (PARTITION BY castingID ORDER BY TemperatureDateTime) AS RN
        FROM Temperatures
)
SELECT
    * 
FROM cte AS c
INNER JOIN (
    SELECT
        castingID
        ,CEILING(CONVERT(DECIMAL(7,2),MAX(RN)) / 2) AS med
    FROM cte
    GROUP BY castingID
) AS m ON c.rn = m.med AND c.castingID = m.castingID

这是一个包含查询结果的 SQL Fiddle: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=5b3aebf3ab4ced946c90a435d9edce3c

共有三个用例(都有不同的

castingID
)。

1.) 奇数行

2.) 偶数行

3.) 单行


0
投票

这是没有 WHERE 工作的查询

SELECT *
FROM Customers
ORDER BY customer_id 
LIMIT 1 OFFSET (SELECT COUNT(*) / 2 FROM Customers) - 1;

© www.soinside.com 2019 - 2024. All rights reserved.