【问题标题】:Can I get the position of a record in a SQL result table?我可以在 SQL 结果表中获取记录的位置吗?
【发布时间】:2009-05-25 17:12:25
【问题描述】:

如果我这样做

SELECT * FROM mytable ORDER BY mycolumn ASC;

我得到一个按特定顺序排列的结果表。

在给定 PK 的情况下,SQL 中有没有一种方法可以有效地找出结果表中的哪个位置会包含我的 PK 的记录?

【问题讨论】:

    标签: sql sql-order-by


    【解决方案1】:

    您可以计算您正在排序的值的值低于您知道其键值的记录的记录数:

    select count(*)
    from mytable
    where mycolumn < (select mycolumn from mytable where key = 42)
    

    【讨论】:

    • +1 简单且不依赖于 ROW_NUMBER()。尽管您需要将 1 添加到结果中,或者机会
    • 是的,如果您希望位置从 1 开始,而不是从 0 开始。
    • 一个附带条件:此方法仅适用于唯一键(PK 将是)
    • @JanM:不完全是。它不一定是一个键,它只是你比较的一个值必须只出现一次。
    【解决方案2】:

    在支持它的数据库上,您可以为此目的使用 ROW_NUMBER():

    SELECT RowNr
    FROM (
        SELECT 
             ROW_NUMBER() OVER (ORDER BY mycolumn) AS RowNr,
             mycolumn
        FROM mytable
    ) sub
    WHERE sub.mycolumn = 42
    

    该示例假设您正在寻找主键 42 :)

    子查询是必要的,因为类似:

    SELECT 
         ROW_NUMBER() OVER (ORDER BY mycolumn) AS RowNr
    FROM mytable
    WHERE sub.mycolumn = 42
    

    总是返回 1; ROW_NUMBER() 在 WHERE 之后起作用,可以这么说。

    【讨论】:

    • 为什么投反对票?这对于支持 ROW_NUMBER 的数据库引擎是正确且有用的(这与替代方案相比有多快,像往常一样,需要对给定数据库进行特定测量)。
    • 这是一个完美的 SQL Server 解决方案。
    • 我没有投反对票,但是 OP 并没有说他使用的是 Microsoft SQL Server。他可能是,但他没有这么说或标记他的问题。
    • 在投反对票之前,vagon cuz 是“特定于 m$”的,请花一分钟时间和 RTFM。 ROW_NUMBER、RANK、DENSE_RANK、PERCENT_RANK 和 CUME_DIST 是 ANSI 标准 SQL-2003 中指定的窗口函数,所有主要供应商都支持或计划很快支持它们。
    • 行号的问题是它没有给你“表格中的位置”。它为您提供了该特定结果集中的位置。这可能是提问者想要的,但它并没有真正回答所问的问题。
    【解决方案3】:

    SQL 不能那样工作。它是基于集合的,这意味着“该结果表中的位置”对数据库没有意义。

    您可以在将 ResultSet 映射到对象集合或对其进行迭代时跟踪位置。

    【讨论】:

    • +1 出色的答案。 SQL Server 不再像 dBase - 不再有“记录 + 1”之类的东西。
    • 如果位置没有意义,那么ORDER BY是干什么用的?还是 LIMIT、TOP 和 ROW_NUMBER?
    • LIMIT、TOP 和 ROW_NUMBER() 不是标准 SQL 语言的一部分。
    • 我认为标准 SQL 抽象出“物理行号”。发帖人要问的是ORDER BY序列中一行的位置,在标准SQL中有明确的含义。
    • CREATE INDEX 也不属于任何 SQL 标准。我应该停止使用索引,因为它们不是 ISO 吗?
    【解决方案4】:

    很遗憾,您无法获得“表格中一行的位置”。

    使用 ORDER BY 和 ROW_NUMBER 构造的变体(取决于使用的数据库引擎)可以获得的最佳结果是执行查询的结果集中行的位置。

    这个位置不会映射回表中的任何位置,除非 ORDER BY 在一组聚集索引列上,但即便如此,该位置也可能在下一秒失效。

    我想知道的是你打算用这个“职位”做什么。

    【讨论】:

      【解决方案5】:

      此答案适用于 MySQL

      ==> 低于 8.0

      SET @row_number = 0; 
      SELECT 
          (@row_number:=@row_number + 1) AS num, 
          myColumn.first, 
          myColumn.second
      FROM
          myTable
      ORDER BY myColumn.first, myColumn.second   
      

      来源:http://www.mysqltutorial.org/mysql-row_number/


      ==> 大于 8.0

      请参阅MySQL ROW_NUMBER() function manual,因为我没有测试。但似乎更喜欢这个功能。

      【讨论】:

        【解决方案6】:

        如果不选择整个记录子集,您将无法判断这一点。如果你的 PK 是整数类型,你可以

        select count(*) from mytable 
            where id <= 10 -- Record with ID 10
            order by mycolumn asc
        

        【讨论】:

        • 按id排序时返回位置,'order by'子句无效。
        猜你喜欢
        • 2020-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-07
        • 1970-01-01
        • 1970-01-01
        • 2014-07-05
        • 1970-01-01
        相关资源
        最近更新 更多