11g Oracle聚合SQL查询

时间:2017-01-27 15:48:34

标签: oracle oracle11g aggregate-functions

是否可以帮助我获取此方案的查询。在下面的情况下,它应该返回我A = 13的单行,因为A列中的13,14具有最多的出现次数,而B(30)的值对于13来说更大。我们感兴趣的是A的最大出现,并且在B的情况下应该被视为打破平局。

A   B
13  30
13  12
14  10
14  25
15  5

在以下情况下,单次出现A(全部并列),应该返回14,最大值为40.

A   B
13  30
14  40
15  5

用例 - 我们接到企业客户的电话。我们有兴趣知道大多数电话来自哪个小时,如果是平局,哪个最繁忙时段的通话时间最长。

进一步的问题

还有其他问题。我想使用两种解决方案中的任何一种 - ' 11g或更低'来自@GurV或' dense_rank'来自@mathguy在更大的查询下面我该怎么做。

    SELECT dv.id , u.email , dv.email_subject AS headline , dv.start_date , dv.closing_date, b.name AS business_name, ls.call_cost, dv.currency,
    SUM(lsc.duration) AS duration,  COUNT(lsc.id) AS call_count, ROUND(AVG(lsc.duration), 2) AS avg_duration 
    -- max(extract(HOUR from started )) keep (dense_rank last order by count(duration), max(duration)) as most_popular_hour
    FROM deal_voucher dv
        JOIN lead_source ls ON dv.id = ls.deal_id
        JOIN lead_source_call lsc ON ls.PHONE_SID = lsc.phone_number_id
        JOIN business b ON dv.business_id = b.id
        JOIN users u ON b.id = u.business_id
        AND TRUNC(dv.closing_date) = to_date('13-01-2017', 'dd-mm-yyyy')
        AND lsc.status = 'completed' and lsc.duration >= 30
    GROUP BY dv.id , u.email , dv.email_subject , dv.start_date , dv.closing_date, b.name, ls.call_cost, dv.currency
--, extract(HOUR from started )

2 个答案:

答案 0 :(得分:2)

如果12c +

,请尝试此操作
select a
from t
group by a
order by count(*) desc, max(b) desc
fetch first 1 row only;

如果是11g或更低:

select * from (
    select a
    from t
    group by a
    order by count(*) desc, max(b) desc
) where rownum = 1;

请注意,如果A的两个或多个值有相等的计数和相等的最大值,则将获取其中任何一个。

答案 1 :(得分:0)

这是一个适用于旧版本(无fetch子句)且不需要子查询的查询。它使用first/last函数。如果“由A计数”和“最大值(B)”都绑定,则它仅选择具有最大值A的行。您可以将其更改为min(A),甚至更改为{{1} (虽然这可能对你的问题没有意义)或sum(A)得到一个以逗号分隔的A列表,这些列表与第一名并列,但这需要11.2(我相信)。

LISTAGG(A, ',') WITHIN GROUP (ORDER BY A)