我有一個數據庫列(表示訪問網站)的時間列表。對日期時間列表的累積頻率的SQL查詢
我需要他們組的間隔,然後獲取這些日期的「累積頻率」表。
比如我可能有:
9:01
9:04
9:11
9:13
9:22
9:24
9:28
,我想將其轉換成
9:05 - 2
9:15 - 4
9:25 - 6
9:30 - 7
我怎麼能這樣做?我可以在SQL中輕鬆實現這一點嗎?我可以很容易地做到這一點在C#
我有一個數據庫列(表示訪問網站)的時間列表。對日期時間列表的累積頻率的SQL查詢
我需要他們組的間隔,然後獲取這些日期的「累積頻率」表。
比如我可能有:
9:01
9:04
9:11
9:13
9:22
9:24
9:28
,我想將其轉換成
9:05 - 2
9:15 - 4
9:25 - 6
9:30 - 7
我怎麼能這樣做?我可以在SQL中輕鬆實現這一點嗎?我可以很容易地做到這一點在C#
創建一個表periods
描述你想成劃分一天的時間段。
SELECT periods.name, count(time)
FROM periods, times
WHERE period.start <= times.time
AND times.time < period.end
GROUP BY periods.name
我應該指出的是,根據問題的規定「意圖」,做分析訪客流量 - 我寫了這個說法來概括制服團體計數。
要否則做(如在「實例」基團)在10分鐘的間隔5分鐘的時間間隔爲計數期間將被比較的計數 - 這是沒有意義的。
你神交到的用戶需求,而不是它的字面「讀書」,「意圖」。 :-)
create table #myDates
(
myDate datetime
);
go
insert into #myDates values ('10/02/2008 09:01:23');
insert into #myDates values ('10/02/2008 09:03:23');
insert into #myDates values ('10/02/2008 09:05:23');
insert into #myDates values ('10/02/2008 09:07:23');
insert into #myDates values ('10/02/2008 09:11:23');
insert into #myDates values ('10/02/2008 09:14:23');
insert into #myDates values ('10/02/2008 09:19:23');
insert into #myDates values ('10/02/2008 09:21:23');
insert into #myDates values ('10/02/2008 09:21:23');
insert into #myDates values ('10/02/2008 09:21:23');
insert into #myDates values ('10/02/2008 09:21:23');
insert into #myDates values ('10/02/2008 09:21:23');
insert into #myDates values ('10/02/2008 09:26:23');
insert into #myDates values ('10/02/2008 09:27:23');
insert into #myDates values ('10/02/2008 09:29:23');
go
declare @interval int;
set @interval = 10;
select
convert(varchar(5), dateadd(minute,@interval - datepart(minute, myDate) % @interval, myDate), 108) timeGroup,
count(*)
from
#myDates
group by
convert(varchar(5), dateadd(minute,@interval - datepart(minute, myDate) % @interval, myDate), 108)
retuns:
timeGroup
--------- -----------
09:10 4
09:20 3
09:30 8
不累計... – KristoferA 2008-10-03 04:19:20
它使用了不少招數SQL(SQL Server 2005中):
CREATE TABLE [dbo].[stackoverflow_165571](
[visit] [datetime] NOT NULL
) ON [PRIMARY]
GO
;WITH buckets AS (
SELECT dateadd(mi, (1 + datediff(mi, 0, visit - 1 - dateadd(dd, 0, datediff(dd, 0, visit)))/5) * 5, 0) AS visit_bucket
,COUNT(*) AS visit_count
FROM stackoverflow_165571
GROUP BY dateadd(mi, (1 + datediff(mi, 0, visit - 1 - dateadd(dd, 0, datediff(dd, 0, visit)))/5) * 5, 0)
)
SELECT LEFT(CONVERT(varchar, l.visit_bucket, 8), 5) + ' - ' + CONVERT(varchar, SUM(r.visit_count))
FROM buckets l
LEFT JOIN buckets r
ON r.visit_bucket <= l.visit_bucket
GROUP BY l.visit_bucket
ORDER BY l.visit_bucket
注意,它把所有的時間在同一天,並假定他們是在一個日期時間列。它唯一不能做的就是從時間表示中去掉前導零。
創建一個包含你想在隨後的兩個表聯合起來獲得總計什麼間隔表。
如:
time_entry.time_entry
-----------------------
2008-10-02 09:01:00.000
2008-10-02 09:04:00.000
2008-10-02 09:11:00.000
2008-10-02 09:13:00.000
2008-10-02 09:22:00.000
2008-10-02 09:24:00.000
2008-10-02 09:28:00.000
time_interval.time_end
-----------------------
2008-10-02 09:05:00.000
2008-10-02 09:15:00.000
2008-10-02 09:25:00.000
2008-10-02 09:30:00.000
SELECT
ti.time_end,
COUNT(*) AS 'interval_total'
FROM time_interval ti
INNER JOIN time_entry te
ON te.time_entry < ti.time_end
GROUP BY ti.time_end;
time_end interval_total
----------------------- -------------
2008-10-02 09:05:00.000 2
2008-10-02 09:15:00.000 4
2008-10-02 09:25:00.000 6
2008-10-02 09:30:00.000 7
如果不是想要你的範圍內通緝總數累積總數,然後添加一個TIME_START列到TIME_INTERVAL表和查詢更改爲
SELECT
ti.time_end,
COUNT(*) AS 'interval_total'
FROM time_interval ti
INNER JOIN time_entry te
ON te.time_entry >= ti.time_start
AND te.time_entry < ti.time_end
GROUP BY ti.time_end;
create table accu_times (time_val datetime not null, constraint pk_accu_times primary key (time_val));
go
insert into accu_times values ('9:01');
insert into accu_times values ('9:05');
insert into accu_times values ('9:11');
insert into accu_times values ('9:13');
insert into accu_times values ('9:22');
insert into accu_times values ('9:24');
insert into accu_times values ('9:28');
go
select rounded_time,
(
select count(*)
from accu_times as at2
where at2.time_val <= rt.rounded_time
) as accu_count
from (
select distinct
dateadd(minute, round((datepart(minute, at.time_val) + 2)*2, -1)/2,
dateadd(hour, datepart(hour, at.time_val), 0)
) as rounded_time
from accu_times as at
) as rt
go
drop table accu_times
結果於:
rounded_time accu_count
----------------------- -----------
1900-01-01 09:05:00.000 2
1900-01-01 09:15:00.000 4
1900-01-01 09:25:00.000 6
1900-01-01 09:30:00.000 7
哦,太複雜了,所有這些東西。
正常化秒,通過你的水桶區間劃分,截短和remultiply:
select sec_to_time(floor(time_to_sec(d)/300)*300), count(*)
from d
group by sec_to_time(floor(time_to_sec(d)/300)*300)
使用羅恩野人的數據,我得到
+----------+----------+
| i | count(*) |
+----------+----------+
| 09:00:00 | 1 |
| 09:05:00 | 3 |
| 09:10:00 | 1 |
| 09:15:00 | 1 |
| 09:20:00 | 6 |
| 09:25:00 | 2 |
| 09:30:00 | 1 |
+----------+----------+
您不妨使用小區()或圓形( )而不是floor()。
更新:對於
create table d (
d datetime
);
創建表這不會得到剩餘物,要求累計總量,去掉了「period.start <= times.time」語句將實現這一點,因爲我的回答顯示。 – ManiacZX 2008-10-03 03:55:48
是的。我誤解了這個問題。 – ephemient 2008-10-03 03:58:05