【问题标题】:SQL Server FETCH NEXT X ONLY based on a specific columnSQL Server FETCH NEXT X ONLY 基于特定列
【发布时间】:2022-01-11 18:30:32
【问题描述】:

我有一个要求获得一些在线课程。

这是我可以获得的结果示例:

course_code | course_date | participant_name
------------+-------------+------------------
21175A      | 2021-12-01  | Jon Doe
21175A      | 2021-12-01  | Lisa Tia
21175A      | 2021-13-01  | Jon Doe
21175A      | 2021-13-01  | Lisa Tia

如您所见,我会根据日期和参与者获得同一课程的多行,因此我必须在 PHP 中执行一些过程以将所有内容放入带有键的数组中 (course_code)

我想进行分页以获取前 25 门课程(而不是行)

SELECT course_code, course_date, participant_name 
FROM courses
ORDER BY course_date
OFFSET 0
FETCH NEXT 25 ROWS ONLY

这行不通,因为一门课程可以占用多行(此处为 4 行)。所以我想知道即使有 100 行,我是否可以编写一个查询来获取前 25 门课程(基于 course_code 列)。

你有什么想法吗?提前谢谢你

编辑:这就是我所做的:

WITH cte AS 
(
    SELECT course_code
    FROM courses
    WHERE course_date <= '2021-12-31'
    ORDER BY course_code
    OFFSET 0 ROWS
    FETCH NEXT 25 ROWS ONLY
)
SELECT * 
FROM courses
INNER JOIN cte ON cte.course_code = courses.course_code
WHERE course_date <= '2021-12-31'

我在两者中都添加了WHERE 子句以使请求变慢

【问题讨论】:

  • 首先使用 CTE 获取您的 25 门课程,然后加入其中以获取剩余数据
  • @Stu 是的,谢谢你,我就是这么做的!
  • 如果您出于性能原因进行分页,您可能需要查看Keyset Pagination,它比按行号分页性能要好得多

标签: sql sql-server pagination


【解决方案1】:

使用DENSE_RANK:

WITH cte AS (
    SELECT *, DENSE_RANK() OVER (ORDER BY course_code) dr
    FROM courses
)

SELECT course_code, course_date, participant_name
FROM cte
WHERE dr <= 25
ORDER BY course_date;

对于分页部分,只需更改WHERE 子句中的不等式即可。例如,要获取每页 25 门课程的第二页,您可以使用 WHERE dr &gt; 25 AND dr &lt;= 50

【讨论】:

  • 编辑:它有效,但问题是查询与原始查询花费相同的时间。这不是我正在寻找的,如果它不慢我可以在 PHP 中为分页做一些处理
  • @ErwanPLB - 你可能应该在前端处理这个问题。
  • @ErwanPLB (course_code, course_date, participant_name) 上的索引可能会加快我的回答速度。最后两列也可以出现在INCLUDE 中,而不是 B 树的一部分。
猜你喜欢
  • 2019-05-16
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多