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

发布于 2025-01-18 20:08:27 字数 1062 浏览 4 评论 0原文

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

10735132021-01-0711:
TemperatureID CastingIDTemperatureDateTimeTemperatureValue 14212941648:00.00053
142129510735132021-01-07 11:54:00.0001698
142129610735132021-01-07 11:57:00.0001699

我必须采用 1421295 记录,而偶数要么是 middle + 1 要么 middle - 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

我可以获得我想要的结果还是我必须改变我的方法?

previously I opened an issue asking how to take the first row in a set of records which were resolved brilliantly. Pitifully my customer changed his request a little after so this time I'm asking your help to find the middle row in a set of records i.e. having this:

TemperatureIDCastingIDTemperatureDateTimeTemperatureValue
142129410735132021-01-07 11:53:00.0001648
142129510735132021-01-07 11:54:00.0001698
142129610735132021-01-07 11:57:00.0001699

I have to take the 1421295 record, whereas having an even number either the middle + 1 or middle - 1

So starting from this query, which return the 1421294 record to be clear

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

can I obtain the result I want or I have to change my approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云柯 2025-01-25 20:08:27

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

由于ROW_NUMBER()将为我们提供一组连续的值,为什么不找到MAX(RN)< /code>,除以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.) 单行

Edit: Updated to use a cte.
Edit2: Updated to use a join rather than a sub-select to handle multiple castingIds

Since ROW_NUMBER() is going to give us a continuous set of values, why not find MAX(RN), divide by 2 and then round? If the MAX(RN) is odd, you'll get the true median, if it's even you'll get rounded down. There's likely a cleaner way to do this but something like this:

  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

Here is a SQL Fiddle with the result of the query:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=5b3aebf3ab4ced946c90a435d9edce3c

There's three use cases (all with different castingID).

1.) Odd number of rows

2.) Even number of rows

3.) A single row

疧_╮線 2025-01-25 20:08:27

这是没有工作的查询

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

Here is the query without WHERE work

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文