我构建了一个查询,让我返回某些应用的平均排名。
但是对于他们中的一些人来说,有一个月,我们没有数据,因为该应用程序是一个新的(比方说,该应用程序自本月以来已经出局,所以我们自本月以来收集数据)< / p>
SELECT
DATE_FORMAT(date, '%Y-%m'),
app_id,
AVG(rank)
FROM wadstats.applestore_ranking
where app_id IN (100,
2,
3,
4,
5,
6)
GROUP BY MONTH(date), app_id
ORDER BY CASE WHEN app_id = 100 THEN 1 ELSE 2 END, date ASC
我需要首先显示app_id = 100
但是对于app_id = 8,我没有例证8月的数据。
然后结果看起来像
'2015-07', '100', '3.9355'
'2015-04', '100', '49.5000'
'2015-08', '100', '5.2258'
'2015-05', '100', '16.3333'
'2015-09', '100', '6.1333'
'2015-06', '100', '7.5667'
'2015-10', '100', '5.7727'
'2015-04', '2', '6.0000'
'2015-08', '2', '9.8710'
'2015-05', '2', '6.4667'
'2015-09', '2', '8.9667'
'2015-06', '2', '8.5333'
'2015-10', '2', '9.9545'
'2015-07', '2', '10.5806'
'2015-05', '3', '56.3929'
'2015-09', '3', '55.1667'
'2015-06', '3', '35.2500'
'2015-07', '3', '38.7143'
'2015-04', '3', '38.7500'
'2015-08', '3', '52.5500'
'2015-09', '4', '30.2105'
'2015-06', '4', '27.9231'
'2015-10', '4', '30.0000'
'2015-07', '4', '47.0000'
'2015-08', '4', '32.6818'
'2015-06', '5', '46.8667'
'2015-10', '5', '86.6667'
'2015-07', '5', '63.5185'
'2015-04', '5', '24.2500'
'2015-08', '5', '67.3571'
'2015-10', '6', '30.1818'
我希望每个月都有空,即使这个特定月份没有数据
预期结果
'2015-07', '100', '3.9355'
'2015-04', '100', '49.5000'
'2015-08', '100', '5.2258'
'2015-05', '100', '16.3333'
'2015-09', '100', '6.1333'
'2015-06', '100', '7.5667'
'2015-10', '100', '5.7727'
'2015-04', '2', '6.0000'
'2015-08', '2', '9.8710'
'2015-05', '2', '6.4667'
'2015-09', '2', '8.9667'
'2015-06', '2', '8.5333'
'2015-10', '2', '9.9545'
'2015-07', '2', '10.5806'
'2015-05', '3', '56.3929'
'2015-09', '3', '55.1667'
'2015-06', '3', '35.2500'
'2015-07', '3', '38.7143'
'2015-04', '3', '38.7500'
'2015-08', '3', '52.5500'
'2015-09', '4', '30.2105'
'2015-06', '4', '27.9231'
'2015-05', '4', NULL
'2015-10', '4', '30.0000'
'2015-07', '4', '47.0000'
'2015-08', '4', '32.6818'
'2015-06', '5', '46.8667'
'2015-10', '5', '86.6667'
'2015-07', '5', '63.5185'
'2015-04', '5', '24.2500'
'2015-08', '5', '67.3571'
'2015-04', '6', NULL
'2015-05', '6', NULL
'2015-06', '6', NULL
'2015-07', '6', NULL
'2015-08', '6', NULL
'2015-09', '6', NULL
'2015-10', '6', '30.1818'
如果我需要0而不是NULL,那也没关系,但我需要在数据库中每个月都有,为每个app_id都有价值
非常感谢提前
答案 0 :(得分:3)
下面的查询使用派生表(别名inr
)将YearMonth / app_id组合放在一起。然后,它会在left join
中使用它来获取数据,无论是否存在于表applestore_ranking
中。
如果要显示零而不是NULL,请使用ifnull()
。因此,该部分将成为ifnull(AVG(r.rank),0) as Rank
。
注意,只需简单地将此阶段放在一起然后突出显示inr
选择的代码并查看其简单输出即可。这将使左连接更容易理解。
Helper表的概念一直在sql中使用。有时他们会在飞行中放在一起,然后掉线。其他时候它们是永久性的。
create schema appleSandbox;
use appleSandbox;
-- drop table applestore_ranking;
create table applestore_ranking
( id int auto_increment primary key,
app_id int not null,
date date not null, -- not a great column name
rank int not null
);
-- truncate table applestore_ranking;
insert applestore_ranking (app_id,date,rank) values
(2,'2015-08-01',1),(2,'2015-09-05',10),(2,'2015-09-12',11),(2,'2015-10-01',14),
(6,'2015-10-01',7),(6,'2015-10-05',6),(6,'2015-10-14',2),
(100,'2015-09-01',16),(100,'2015-10-01',16),(100,'2015-10-05',17),(100,'2015-10-14',18);
create table monthHelper
( -- load this up with a few years worth
id int auto_increment primary key,
theDate date not null, -- slightly better column name
wantToSee int not null -- do we want to see it in results or not? 0=no, 1=yes
);
-- note only a few wantToSee have been turned on to 1
insert monthHelper(theDate,wantToSee) values
('2015-05-01',0),('2015-06-01',0),('2015-07-01',0),('2015-08-01',1),('2015-09-01',1),('2015-10-01',1),('2015-11-01',0),('2015-12-01',0),
('2016-01-01',0),('2016-02-01',0),('2016-03-01',0); -- etc
SELECT DATE_FORMAT(inr.theDate, '%Y-%m') as YearMonth, inr.app_id, AVG(r.rank) as Rank
FROM
( select distinct mh.theDate,r.app_id
from monthhelper mh
cross join applestore_ranking r
where mh.wantToSee=1
and r.app_id IN (100,2,3,4,5,6)
) inr
left join applestore_ranking r
on r.app_id=inr.app_id and year(inr.theDate)=year(r.date) and month(inr.theDate)=month(r.date)
GROUP BY MONTH(inr.theDate), inr.app_id
ORDER BY CASE WHEN inr.app_id = 100 THEN 1 ELSE 2 END, inr.theDate ASC
+-----------+--------+---------+
| YearMonth | app_id | Rank |
+-----------+--------+---------+
| 2015-08 | 100 | NULL |
| 2015-09 | 100 | 16.0000 |
| 2015-10 | 100 | 17.0000 |
| 2015-08 | 2 | 1.0000 |
| 2015-08 | 6 | NULL |
| 2015-09 | 2 | 10.5000 |
| 2015-09 | 6 | NULL |
| 2015-10 | 2 | 14.0000 |
| 2015-10 | 6 | 5.0000 |
+-----------+--------+---------+
drop schema AppleSandbox;
答案 1 :(得分:2)
感谢Drew,
这是一种在单个查询中执行的方法,详细解释了我们的详细信息。
非常感谢您使用 CROSS JOIN
的组合提示 SELECT
inr.date AS 'month',
inr.app_id,
r.title,
AVG(r.rank) as 'ranking'
FROM
(
SELECT
DISTINCT DATE_FORMAT(mh.date, '%Y-%m') date,
r.app_id
FROM
applestore_ranking mh
CROSS JOIN
applestore_ranking r
WHERE
mh.app_id = 100
AND
r.app_id IN (100, 1, 2, 3, 4, 5)
) inr
LEFT JOIN
applestore_ranking r ON r.app_id = inr.app_id
AND inr.date = DATE_FORMAT(r.date, '%Y-%m')
GROUP BY
inr.date,
inr.app_id
ORDER BY
CASE WHEN inr.app_id = 100 THEN 1 ELSE 2 END
答案 2 :(得分:0)
这取决于你如何实现你的表 - 它是否包含行,即使没有统计数据(因为它尚未下载),或者这些行/日期是否完全省略?对于后者,你可能想要使用“数字技巧”(解释in great detail here on SO),当你的排名为零的行时,你可以简单地坚持LEFT JOIN
(见MYSQL Documentation)
根据您发布的结果和实际需要的结果进行猜测,您应该选择number trick。