我有一个表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;
答案 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_MODE
和LAST
聚合函数都不会(因为它们倾向于返回找到的第一个模式,不一定是具有最新条目的模式。)
在我的情况下,使用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
就可以了。