我的MySql数据库包含大量带日期(时间戳)的记录和更多属性。 例如,'testTable'看起来像
一个varchar(255)
b int(11)
时间戳bigint(20)
我需要在1月1日到1月15日的一段时间内找到每天总和(b)的前10位,其中这些日期可以由用户指定。
迭代查询将如何? 粗略的方式可能是UNION ALL介于两者之间的单独选择语句。
select a, sum(b) from testTable where FROM_UNIXTIME( timestamp ) between '2012-01-01 05:10:00' and '2012-01-02 05:10:00' group by a order by sum(b) desc LIMIT 10
UNION ALL
select a, sum(b) from testTable where FROM_UNIXTIME( timestamp ) between '2012-01-02 05:10:00' and '2012-01-03 05:10:00' group by a order by sum(b) desc LIMIT 10
UNION ALL
select a, sum(b) from testTable where FROM_UNIXTIME( timestamp ) between '2012-01-03 05:10:00' and '2012-01-04 05:10:00' group by a order by sum(b) desc LIMIT 10
..
..
..
UNION ALL
select a, sum(b) from testTable where FROM_UNIXTIME( timestamp ) between '2012-01-14 05:10:00' and '2012-01-15 05:10:00' group by a order by sum(b) desc LIMIT 10 ;</br>
但是我希望它更通用,用户可以运行具有2个给定日期的脚本。
输出就像
a | FROM_UNIXTIME(时间戳)|总和(b)
----------- + ------------------------ + ------
测试| 2012-01-01 03:24:41-04 | 500
测试| 2012-01-01 03:19:40-04 | 420
测试| 2012-01-01 03:14:39-04 | 261
测试| 2012-01-01 03:09:38-04 | 244
测试| 2012-01-01 03:04:37-04 | 231
测试| 2012-01-01 02:59:36-04 | 223
测试| 2012-01-01 02:54:35-04 | 211
test1 | 2012-01-01 02:49:34-04 | 199
test1 | 2012-01-01 03:24:41-04 | 195
test1 | 2012-01-01 03:19:40-04 | 191
新| 2012-01-02 06:11:06-04 | 1000
新| 2012-01-02 06:06:06-04 | 978
新| 2012-01-02 06:01:06-04 | 867
新| 2012-01-02 05:56:05-04 | 786
新| 2012-01-02 05:51:05-04 | 698
新| 2012-01-02 05:46:05-04 | 598
new1 | 2012-01-02 06:11:06-04 | 476
new1 | 2012-01-02 05:41:04-04 | 345
new2 | 2012-01-02 06:06:06-04 | 250
new2 | 2012-01-02 06:01:06-04 | 125
答案 0 :(得分:1)
试试这个......更改两个范围之间的日期,只传递一次范围。
已修正错误,省略了行,并且缺少逗号:
select day, a, tot
from
(
select
*,
@num := if(@day = tt4.day, @num + 1, 1) as row_number,
@day := tt4.day as dummy
from
(
select
ts as day,
tt1.a,
sum(tt1.b) as tot
from
testTable tt1,
( select distinct date(FROM_UNIXTIME(tt2.timestamp)) as ts
from testTable tt2
where date(FROM_UNIXTIME(tt2.timestamp)) between cast('2012/01/01' as date) and cast('2012/01/15' as date) ) as tt3
where
date(FROM_UNIXTIME(tt1.timestamp)) = tt3.ts
group by
date(FROM_UNIXTIME(tt1.timestamp)),
tt1.a
order by
date(FROM_UNIXTIME(tt1.timestamp)),
sum(tt1.b) desc,
tt1.a
) as tt4
) as tt5
where
tt5.row_number <=10
已修改 - 更改了Vertica的SQL风格...语法可能已关闭(我没有要测试的Vertica安装),但要点就在那里。
select day, a, tot
from
(
select
*,
ROW_NUMBER() OVER (PARTITION BY tt4.day) as row_number
from
(
select
ts as day,
tt1.a,
sum(tt1.b) as tot
from
testTable tt1,
( select distinct date(TO_TIMESTAMP(tt2.timestamp)) as ts
from testTable tt2
where date(TO_TIMESTAMP(tt2.timestamp)) between cast('2012/01/01' as date) and cast('2012/01/15' as date) ) as tt3
where
date(TO_TIMESTAMP(tt1.timestamp)) = tt3.ts
group by
date(TO_TIMESTAMP(tt1.timestamp)),
tt1.a
order by
date(TO_TIMESTAMP(tt1.timestamp)),
sum(tt1.b) desc,
tt1.a
) as tt4
) as tt5
where
tt5.row_number <=10