如何获得最频繁的SQL值

时间:2016-12-08 15:59:06

标签: sql oracle oracle11g

我有一个表Orders(id_trip,id_order),表Trip(id_hotel,id_bus,id_type_of_trip)和table Hotel(id_hotel,name)。

我想在表格订单中获得最常用酒店的名称。

SELECT hotel.name from Orders
 JOIN Trip
 on Orders.id_trip = Trip.id_hotel
 JOIN hotel
 on trip.id_hotel = hotel.id_hotel
  FROM (SELECT hotel.name, rank() over (order by cnt desc) rnk
          FROM (SELECT hotel.name, count(*) cnt
                  FROM Orders
                 GROUP BY hotel.name))
 WHERE rnk = 1;

4 个答案:

答案 0 :(得分:1)

分布中“最常出现的值”是统计中的一个独特概念,具有技术名称。它被称为分布模式。 Oracle具有STATS_MODE()功能。 https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions154.htm

例如,使用标准EMP架构中的SCOTT表,select stats_mode(deptno) from scott.emp将返回30 - 员工最多的部门的编号。 (30是部门“名称”或编号,它不是该部门的雇员人数!)

在你的情况下:

select stats_mode(h.name) from (the rest of your query)

注意:如果两个或更多酒店“最常见”并列,则STATS_MODE()将返回其中一个(非确定性)。如果您需要所有绑定的值,您将需要一个不同的解决方案 - 文档中的一个很好的例子(上面链接)。这是Oracle理解和实施统计概念的一个文档缺陷。

答案 1 :(得分:1)

使用FIRST获得单个结果:

SELECT MAX(hotel.name) KEEP (DENSE_RANK FIRST ORDER BY cnt DESC) 
FROM (
  SELECT hotel.name, COUNT(*) cnt
  FROM orders
  JOIN trip USING (id_trip)
  JOIN hotel USING (id_hotel)
  GROUP BY hotel.name
) t

答案 2 :(得分:0)

这是一种方法:

select name
from (select h.name,
             row_number() over (order by count(*) desc) as seqnum  -- use `rank()` if you want duplicates
      from orders o join
           trip t 
           on o.id_trip = t.id_trip join -- this seems like the right join condition
           hotels h
           on t.id_hotel = h.id_hotel
     ) oth
where seqnum = 1;

答案 3 :(得分:0)

**从数据样本中获取最新的统计模式**

我知道它超过一年,但这是我的答案。我遇到了这个问题,希望找到一个比我所知的更简单的解决方案,但是唉,不。

我遇到了类似的情况,我需要从数据样本中获取模式,如果有多种模式,需要获取最近插入值的模式。

在这种情况下,STATS_MODELAST聚合函数都不会(因为它们倾向于返回找到的第一个模式,不一定是具有最新条目的模式。)

在我的情况下,使用ROWNUM伪列很容易,因为有问题的表是只经历过插入(不是更新)的性能指标表

在这个过于简单的示例中,我使用ROWNUM - 如果您有时间戳或序列字段,可以很容易地将其更改为。

 SELECT     VALUE
       FROM
        (SELECT     VALUE        ,
                COUNT( * ) CNT,
                MAX( R ) R
               FROM
                ( SELECT ID, ROWNUM R FROM FOO
                )
           GROUP BY ID
           ORDER BY CNT DESC,
                R DESC
        )
      WHERE
        (
            ROWNUM < 2
        );

也就是说,得到每个值的总计数和最大ROWNUM(我假设这些值是离散的。如果它们不是,那么这就不行了工作

然后进行排序,以便计数最多的那些首先出现,对于那些具有相同计数的那些,具有最大ROWNUM的那个(在我的情况下表示最近的插入 )。

然后撇去顶行。

您的特定数据模型应该能够识别表中插入的最新(或最旧或任何)行,如果存在冲突,那么除了使用{之外,其他方法并不多{1}}或获取大小为1的随机样本。

如果这不适用于您的具体情况,则您必须创建自己的自定义聚合器。

现在,如果您不关心Oracle将选择哪种模式(您的商业案例只需要一种模式,那么ROWNUM就可以了。