繁体   English   中英

根据全部数据的总数(按日期分组)选择前10名

[英]Select Top 10 Based on Total of Entire Data, Grouped by Date

我有一个简单的表,用于记录在线广播电台的客户端连接。 我正在尝试提出一种观点,该观点将根据整个时段的收听时间返回前10个国家/地区,但按日期和日期分组。

需要说明的是,前10名将是整个时期的前10名,而不仅仅是每天。 例如,美国可能一直是我们排名第一的国家,但有时它可能会下降到12位,我仍然需要每天列出整个前10个国家。

实际上,这应该产生一个视图,每天在哪里会有相同的十个国家/地区,但总收听时间为。

我创建了一个返回所有国家的视图:

SELECT DATE( datetime_end ) , country_code, SUM( duration ) /3600
FROM icecast_logs
WHERE mount = 'live'
GROUP BY DATE( datetime_end ) , country_code

对于MSSQL使用TOP

SELECT TOP 10 DATE(datetime_end), country_code, SUM(duration)/3600
FROM icecast_logs
WHERE mount = 'live'
GROUP BY DATE(datetime_end), country_code
ORDER BY SUM(duration)/3600 DESC

对于MySQL,请使用LIMIT

SELECT DATE(datetime_end), country_code, SUM(duration)/3600
FROM icecast_logs
WHERE mount = 'live'
GROUP BY DATE(datetime_end), country_code
ORDER BY SUM(duration)/3600 DESC
LIMIT 10

对于Oracle,您需要使用RANKROWNUM

WITH  top_icecast_logs AS
(
    SELECT DATE(datetime_end) AS Dateend, country_code, SUM(duration)/3600 AS SumTotalAmount, 
    RANK () OVER (ORDER BY SUM (SumtotalAmount) DESC) AS tsum
    FROM icecast_logs
    GROUP BY DATE(datetime_end), country_code
)
SELECT    Dateend, country_code, SumTotalAmount
FROM      top_icecast_logs 
WHERE     tsum <= 2
ORDER BY  SumTotalAmount DESC;

我设法通过使用INNER JOIN来解决此问题:

SELECT DATE( datetime_end ) , icecast_logs.country_code, SUM( duration ) /3600 FROM icecast_logs
INNER JOIN
(SELECT country_code
FROM icecast_logs
WHERE mount =  'live'
GROUP BY country_code
ORDER BY SUM( duration ) DESC 
LIMIT 10) AS TopTen
ON icecast_logs.country_code = TopTen.country_code

WHERE mount =  'live'
GROUP BY DATE( datetime_end ) , icecast_logs.country_code

据我了解,您需要始终获得前10名收听者(此处为国家/地区)的每日统计信息。

首先,我们选择duration值最高的那10个国家/地区代码,然后每天针对这10个国家/地区中的每个国家/地区打印这些统计信息。

请记住,如果您没有10个国家/地区,则CTE将获取少于10行的数据。 此外,如果某个国家/地区几天未收听,则您的搜索结果中不会显示该国家/地区。 这可以通过首先生成日期,然后将您的数据与这些日期合并以显示每个日期中的每个国家/地区,例如duration_hrs值为0

这应该给您预期的结果。

WITH top_ten_all_time AS (
SELECT
   country_code
FROM
   icecast_logs
WHERE
   mount = 'live'
GROUP BY country_code
ORDER BY SUM(duration) / 3600 DESC
FETCH FIRST 10 ROWS ONLY
)
SELECT
   DATE(a.datetime_end) AS date_x,
   a.country_code,
   SUM(a.duration) / 3600 AS duration_hrs
FROM
   icecast_logs a
   INNER JOIN top_ten_all_time b USING (country_code)
WHERE
   mount = 'live'
GROUP BY DATE(a.datetime_end), a.country_code
ORDER BY date_x, country_code

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM