SQL:排名超过发生

时间:2016-04-26 09:52:11

标签: sql oracle

假设像

这样的表格
PROD   |SIZE|..
-------|----|--
ProdA  |150 |..
ProdA  |200 |..
ProdA  |200 |..
ProdA  |200 |..
ProdB  |150 |..
ProdB  |150 |..
ProdB  |150 |..
ProdC  |200 |..
....   |... |..

我需要一个查询来匹配每个产品最常出现的SIZE,结果是:

PROD   |SIZE|..
-------|----|--
ProdA  |200 |..
ProdB  |150 |..

我想我必须使用一个复杂的rank() over(partition)构造,其中包含一些count(),但不知怎的,我无法弄明白。

我坚持

SELECT
  PROD
, SIZE
FROM (
  SELECT
    PROD
  , SIZE
  , RANK() OVER (PARTITION BY PROD ORDER BY COUNT(SIZE)) AS RANK
)
WHERE
  RANK = 1

编辑:在示例中添加了一列以澄清有更多数据..

2 个答案:

答案 0 :(得分:0)

Oracle使用函数STATS_MODE来返回最常用的值:

select prod, stats_mode(size)
from mytable
group by prod;

如果是关系(即两个或更多个大小共享最高频率),你可以随意得到一个。

这是RANK查询,即使是关系。我们使用RANK按频率对每个产品的汇总记录(即产品尺寸)进行排名,并仅保留最佳排名尺寸(排名#1)。

select prod, size
from
(
  select 
    prod, 
    size,
    rank() over (partition by prod order by count(*) desc) as rnk
  from mytable
  group by prod, size
)
where rnk = 1;

答案 1 :(得分:0)

你也可以尝试这个。希望它有所帮助。

SELECT C.*
FROM
  (SELECT B.*,
    ROW_NUMBER() OVER(PARTITION BY B.CD ORDER BY B.RN DESC) RNK
  FROM
    (SELECT A.*,
      COUNT(A.QT) OVER(PARTITION BY A.CD,A.QT ORDER BY A.CD DESC) RN
    FROM
      (SELECT 1 AS CD, 200 QT FROM DUAL
      UNION ALL
      SELECT 1 AS CD, 200 QT FROM DUAL
      UNION ALL
      SELECT 1 AS CD, 200 QT FROM DUAL
      UNION ALL
      SELECT 1 AS CD, 150 QT FROM DUAL
      UNION ALL
      SELECT 2 AS CD, 100 QT FROM DUAL
      UNION ALL
      SELECT 2 AS CD, 150 QT FROM DUAL
      UNION ALL
      SELECT 2 AS CD, 100 QT FROM DUAL
      UNION ALL
      SELECT 2 AS CD, 500 QT FROM DUAL
      UNION ALL
      SELECT 1 AS CD, 100 QT FROM DUAL
      )A
    ) B
  )C
WHERE C.RNK = 1 ;