查询具有最多读取次数的ID

时间:2016-02-11 16:41:23

标签: sql oracle

假设我有一个类似下面的表:

+----+-----------+
| ID |   TIME    |
+----+-----------+
|  1 | 12-MAR-15 |
|  2 | 23-APR-14 |
|  2 | 01-DEC-14 |
|  1 | 01-DEC-15 |
|  3 | 05-NOV-15 |
+----+-----------+

我想要做的是每年(年份定义为DATE),列出该年度计数最高的ID。例如,ID 1在2015年发生最多,ID 2在2014年发生最多,等等。

查询的内容是:

SELECT EXTRACT(year from time) "YEAR", COUNT(ID) "ID"
FROM table
GROUP BY EXTRACT(year from time)
ORDER BY COUNT(ID) DESC;

但是这个查询只计算一年发生的次数,如何将其修复到当年ID的最高数量?

输出:

+------+----+
| YEAR | ID |
+------+----+
| 2015 |  2 |
| 2012 |  2 |
+------+----+

预期输出:

+------+----+
| YEAR | ID |
+------+----+
| 2015 |  1 |
| 2014 |  2 |
+------+----+

3 个答案:

答案 0 :(得分:2)

从您的示例查询开始,第一个更改只是按ID和年份进行分组。

SELECT EXTRACT(year from time) "YEAR" , id, COUNT(*) "TOTAL"
FROM table
GROUP BY EXTRACT(year from time), id
ORDER BY EXTRACT(year from time) DESC, COUNT(*) DESC

通过这种方式,您可以通过目视检查找到所需的行(每年的第一行是行数最多的ID)。

要让查询返回总数最高的行,有几种不同的方法可以执行此操作。如果存在关联,你需要考虑你想要做什么 - 你想看到所有ID在一年中最高,或者只是一个任意的?

这是一种方法 - 如果存在平局,则应该只返回最低的绑定ID:

WITH groups AS (
  SELECT EXTRACT(year from time) "YEAR" , id, COUNT(*) "TOTAL"
  FROM table
  GROUP BY EXTRACT(year from time), id
)
SELECT year, MIN(id) KEEP (DENSE_RANK FIRST ORDER BY total DESC)
FROM groups
GROUP BY year
ORDER BY year DESC

答案 1 :(得分:2)

您需要计算每个ID,然后对该计数应用RANK:

SELECT *
FROM
 (
   SELECT EXTRACT(year from time) "YEAR" , ID, COUNT(*) AS cnt
      , RANK() OVER (PARTITION BY "YEAR" ORDER BY COUNT(*) DESC) AS rnk
   FROM table
   GROUP BY EXTRACT(year from time), ID
 ) dt
WHERE rnk = 1

如果这会返回每年具有相同高计数的多行,并且您只想随机选择其中一行,则可以切换到ROW_NUMBER。

答案 2 :(得分:0)

这应该做你以后的事情,我想:

{{1}}