【问题标题】:Retrieve Rank from sqlite table从 sqlite 表中检索排名
【发布时间】:2011-04-15 22:20:01
【问题描述】:

假设我在 sqlite DB 中有一个表,其中包含两个字段:名称和年龄。

Bob|40
Rob|50
Zek|60

如何查询 Zek 的 sqlite 表并确定他是最老的?更一般地说,假设我有数百万个姓名和年龄,我想查询一个特定条目,比如 name="Juju Bear",然后通过不同的字段查找条目的排名,例如那个“juju熊”排名133455(按年龄)。

谢谢,

科罗拉多

【问题讨论】:

  • 我知道您提供了一个简化的示例——但存储的是出生日期或年份,而不是年龄本身,然后计算年龄。不要存储年龄本身。如果我没有多次看到这样做,我就不会写这篇评论了。
  • 好点,年龄变化不是吗?

标签: sql sqlite


【解决方案1】:

您可以使用子查询来统计年龄较大的人数,例如:

select  p1.*
,       (
        select  count(*) 
        from    People as p2
        where   p2.age > p1.age
        ) as AgeRank
from    People as p1
where   p1.Name = 'Juju bear'

【讨论】:

    【解决方案2】:

    Andomar 的答案很好,几乎可以肯定它应该是这个问题的选定答案。也就是说……

    当我试图将它硬塞到 Andomar 的解决方案中时,我发现我正在运行的一个复杂查询很快变得笨拙,所以出于绝望,我尝试使用类似以下代码的代码:

    CREATE TABLE DoughnutShopCountsByHood AS 
    SELECT Neighborhood, COUNT(*) AS DoughnutShopCount FROM 
    (  <<crazy-set-of-painful-subqueries-removed>>  )
    GROUP BY Neighborhood ORDER BY DoughnutShopCount DESC;
    

    重要的部分是第一行的“CREATE TABLE ... AS”部分。我原本计划这只是几个步骤中的第一步,但至少在 Firefox 的 SQLite 管理器中,我惊喜地发现,当我将长得可笑的查询转储到一个新表中时,RDBMS 只是自动添加了一个索引列。此列很好地兼作“排名”列。

    我意识到这是一个非常古老的问题,所以这个答案可能不会得到任何支持,但我发布它以防我的个人经验可以帮助其他面临类似挑战的人。

    再次感谢 Andomar 的原始答案——我想这对大多数人来说是最有帮助的。

    【讨论】:

      【解决方案3】:

      SQLite 有一个 RANK() 函数

      SELECT
          *,
          RANK () OVER ( 
              ORDER BY age DESC
          ) age_rank
      FROM
          yourtable
      

      这将返回所有条目,新的第三行表示他们的年龄等级

      在我的测试中,这也会按照 RANK() 中的指定顺序对结果进行排序

      请记住,您添加的任何 WHERE 子句都会影响排名,为了获得 一个 元素的排名,您需要一些嵌套语句

      SELECT 
          * 
      FROM (
          SELECT
              *,
              RANK () OVER ( 
                  ORDER BY age DESC
              ) age_rank
          FROM
              yourtable
      ) 
      WHERE 
          name = "Zek";
      

      您还可以通过嵌套语句获得nth 最旧的

      SELECT 
          * 
      FROM (
          SELECT
              *,
              RANK () OVER ( 
                  ORDER BY age DESC
              ) age_rank
          FROM
              yourtable
      ) 
      WHERE 
          age_rank = 2;
      

      我在测试中发现的一件可能很重要的事情是,所有相同的值都具有相同的等级。我个人认为这很好,但可能很重要

      RANK() OVER (
          PARTITION BY <expression1>[{,<expression2>...}]
          ORDER BY <expression1> [ASC|DESC], [{,<expression1>...}]
      )
      

      pretty good tutorial i found

      reference to it in official docs though does not explain how it works

      当然,sqlite 的“乐趣”是每个实现都是不同的,虽然它在官方文档中,所以我无法想象它会那么罕见

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-17
        • 2015-01-11
        • 1970-01-01
        • 2019-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多