【问题标题】:SQL Server Select top 10-20 results?SQL Server 选择前 10-20 个结果?
【发布时间】:2023-04-08 05:44:02
【问题描述】:

我有两列第一个我想要前 10 名产品 (1-10)

那是

SELECT TOP 10 * FROM Product   

在第二列中我想要接下来的 10 个结果 (11-20)

我该怎么做?

【问题讨论】:

  • 请问什么版本的 SQL Server?
  • MySql 或 SQLServer 什么平台?
  • 在 SQL Server 2011(代号“denali”)中,您将能够做到 SELECT * FROM Table ORDER BY Something OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY,这非常棒:)
  • @AlexBagnolini 你能把它作为答案,因为它现在真的是更正确的答案吗? - 如果没有答案,人们可​​能会在 cmets 中错过它。
  • @MartinSmith True,5 年后重读这些问题我可以看到 :)

标签: sql sql-server


【解决方案1】:
WITH T AS
(
SELECT TOP 20 name, 
       row_number() OVER (ORDER BY id) AS RN
FROM Products
ORDER BY id
)
SELECT 
       MAX(CASE WHEN RN <=10 THEN name END) AS Col1,
       MAX(CASE WHEN RN > 10 THEN name END) AS Col2
FROM T       
GROUP BY RN % 10

【讨论】:

  • 我必须承认我非常喜欢阅读 Martin 和 Marc 的解决方案。两者都 +1
  • +1 darn - 这比我的解决方案更聪明,执行计划的“负担”更少 - 恭喜!
  • @marc_s 这就是我喜欢阅读的意思。不同的方法和解决方案让我(至少)以更好的方式思考:)
  • @niktrs:确实 - 我也喜欢看到其他(非常聪明!)人的解决方案 - 帮助我每天都做得更好! :-) (这里的 Martin 肯定是顶级 SQL 大师之一 - 已经保存了我的培根几次 :-) 谢谢 Martin!)
  • 感谢 cmets 的自我提升!
【解决方案2】:

我会这样做:

SELECT [columns] FROM [table names] ORDER BY [column name] DESC LIMIT 10 OFFSET 10;

这更简单,也不那么复杂....

你们觉得呢?

【讨论】:

  • 它似乎不适用于 SQL Server,但是如果您将 LIMIT 10 OFFSET 10 替换为 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;然后它将在 SQL Server 上运行。
【解决方案3】:
select top 10 wwwhid from wwwh  where wwwhid not in(select top 10 wwwhid from wwwh)

【讨论】:

  • 聪明敏锐
  • @KhurramShaikh 谢谢
【解决方案4】:

从 SQL server 2012 开始order by offset/fetch 功能:

SELECT *
FROM SomeTable
ORDER BY someIdField 
    OFFSET 10 ROWS
    FETCH NEXT 10 ROWS ONLY;

【讨论】:

    【解决方案5】:

    在 SQL Server 中,完成这项工作有点棘手。如果您使用的是 SQL Server 2005 或更高版本,则可以使用带有 CROSS JOIN 的 CTE 和一些技巧来获得您正在寻找的结果:

    ;WITH TopProducts AS
    (
        SELECT 
            ProductID, ProductName,
            ROW_NUMBER() OVER(ORDER BY --some-column-here-- DESC) 'RN'
        FROM dbo.Products
    )
    SELECT 
        p1.ProductID, p1.ProductName,
        p2.ProductID, p2.ProductName
    FROM 
        TopProducts p1
    CROSS JOIN 
        TopProducts p2
    WHERE 
        p1.RN BETWEEN 1 AND 10        -- get rows 1-10 from the first CTE
        -- AND p2.RN BETWEEN 11 AND 20   redundant, as niktrs pointed out
        AND p1.RN + 10 = p2.RN        -- join rows from P1 and P2 so you don't get a cartesian product
    

    CTE(通用表表达式)对产品进行编号 - 这需要基于您的 Products 表中的某些列,但您没有提及定义顺序的列。

    然后,我们从 CTE 中选择第 1-10 行,以及从 CTE 的第二个实例中选择第 11-20 行。如果保持原样,您将获得 100 行 - 第一个结果集中的第 1-10 行的每个组合与第二个结果集中的 10 行中的每一个组合。

    这就是为什么您需要基于行号的附加条件来“连接”每个结果集中的一行,因此您将获得十行 - 第一列包含 Products 表中的项目 1-10 ,第二列有第 11-20 行

    【讨论】:

    • 虽然我认为这会比我的代码执行得更好,但在我的测试环境中会进行两次索引扫描而不是索引搜索?!我也认为 AND p2.RN BETWEEN 11 AND 20 是多余的,因为 AND p1.RN + 10 = p2.RN
    • @niktrs:关于冗余,你是对的 - 甚至可以将其写为 INNER JOIN 并将 p1.RN = p2.RN - 10 作为 JOIN 条件 - 也可以
    • @marc_s:我认为从逻辑上讲,这一个内部连接。无论如何,+1,它的工作是正确的。
    【解决方案6】:

    我不确定这是不是最好的方法,但它确实有效

    select *
    from
    (
    SELECT top 10 ROW_NUMBER() OVER(ORDER BY product) linenum, product
    FROM products
    ) t1
     JOIN 
    (
    SELECT top 20 ROW_NUMBER() OVER(ORDER BY product) linenum, product
    FROM products
    ) t2 ON t1.linenum+10 = t2.linenum
    

    【讨论】:

    • 我认为这将导致前 10 行在两列中显示两次,一次单独显示,一次与其他 10 列一起显示。也许您的意思是 INNER JOIN 而不是 FULL JOIN?还是我错过了什么?
    【解决方案7】:
    declare @FromRange int
    declare @ToRange int
    set @FromRange =11
    set @ToRange =20
    SELECT top(@ToRange-@FromRange+1) * FROM [tbl] 
    where tbl_id not in (select top (@FromRange-1) tbl_id from tbl)
    ORDER BY tbl_id 
    

    【讨论】:

    • 对我来说也是最好的答案。非常感谢
    • select top (@FromRange-1) tbl_id from tbl ORDER BY tbl_id 第二个查询也需要
    【解决方案8】:
    SELECT * FROM Product LIMIT(10,10)
    

    【讨论】:

    • SQL Server 没有LIMIT
    • 没有版本或版本的 SQL Server 支持 LIMIT - 这是 MySQL 的自定义特性 - 根本不是任何标准
    【解决方案9】:

    试试这个:

    SELECT * 
    FROM 
    ( 
        SELECT TOP 10 ROW_NUMBER() OVER(ORDER BY ColName) RowNo, ColName
        FROM TableName 
    ) table1 
    INNER JOIN  
    ( 
        SELECT TOP 20 ROW_NUMBER() OVER(ORDER BY ColName) RowNo, ColName 
        FROM TableName 
    ) table2 ON table1.RowNo + 10 = table2.RowNo 
    

    【讨论】:

      【解决方案10】:
      WITH result_set AS 
          (SELECT ROW_NUMBER() OVER 
              (ORDER BY Product.ID DESC) AS 
           [row_number], Product.intId AS id, Product.Title As Title
           FROM Product WHERE Product.Price > 11)
      SELECT * FROM result_set WHERE [row_number] BETWEEN 10 AND 19 
      

      【讨论】:

        【解决方案11】:

        使用代码:

        select top 20 * from [table Name] 
        except
        select top 10 * from [table Name]
        

        【讨论】:

          【解决方案12】:
          SELECT p.* FROM 
          (
           SELECT *, ROW_NUMBER() OVER (ORDER BY /*some column*/) AS row_num
           FROM Product
          ) AS p
          WHERE p.row_num BETWEEN 11 AND 20
          

          【讨论】:

            【解决方案13】:
            select *
            from (select *
                  from <table>
                  order by id asc)
            where rownum <= 20
            
            minus
            select *
            from (select *
                  from <table>
                  order by id asc)
            where rownum <= 10
            

            【讨论】:

            • 欢迎来到 Stack Overflow :-) 随时联系tour
            【解决方案14】:

            试试这个:

            SELECT * FROM
              (SELECT ROW_NUMBER() OVER (ORDER BY ColumnName) AS MyRowNumber, *
              FROM TableName) tbl
            WHERE MyRowNumber BETWEEN 20 AND 30
            

            【讨论】:

              【解决方案15】:

              您可以使用以下 SQL 查询来执行此操作:

              SELECT * FROM [table] LIMIT 10 OFFSET 10
              

              这将从我的表中选择行,它会给我 10 行,并会跳过前 10 行。

              【讨论】:

              • 这是 MySQL,但 OP 要求使用 SQL Server。
              【解决方案16】:

              这是最具体的:

              SELECT Col1, Col2, Col3  FROM
              (SELECT ROW_NUMBER() OVER (ORDER BY Id) AS MyRowNumber, * FROM table) tbl
              WHERE MyRowNumber BETWEEN 11 AND 20;
              

              【讨论】:

                猜你喜欢
                • 2019-10-26
                • 1970-01-01
                • 2011-02-05
                • 1970-01-01
                • 1970-01-01
                • 2023-03-22
                • 1970-01-01
                • 2015-12-29
                • 1970-01-01
                相关资源
                最近更新 更多