Chi*_*kar 3 sql-server sql-server-2008-r2 count date
我有一个包含通话记录的表:
tbl_calls
cl_Id
cl_StartDate
cl_endDate
Run Code Online (Sandbox Code Playgroud)
我传递两个参数@StartDate
并@EndDate
给我的存储过程。
我的要求是在每 15 分钟的持续时间内获取通话记录的数量。
例如,如果:
@StartDate = '2015-11-16 00:00:00.000',
@EndDate = '2015-11-16 23:59:00.000'
Run Code Online (Sandbox Code Playgroud)
输出应该是:
Date Count
2015-11-16 00:00:00.000 10(Count of startDate between '2015-11-16 00:00:00.000' AND '2015-11-16 00:15:00.000')
2015-11-16 00:15:00.000 7(Count of startDate between '2015-11-16 00:15:00.000' AND '2015-11-16 00:30:00.000')
2015-11-16 00:30:00.000 50(Count of startDate between '2015-11-16 00:30:00.000' AND '2015-11-16 00:45:00.000')
upto @EndDate
Run Code Online (Sandbox Code Playgroud)
我已经尝试了以下查询,但它不能正常工作。有一个更好的方法吗?
DECLARE @StartDate DATETIME = DATEADD(DAY,-1,GETUTCDATE()),
@EndDate DATETIME = GETUTCDATE()
SELECT New
FROM
(SELECT
(CASE
WHEN cl_StartTime BETWEEN @StartDate AND
DATEADD(MINUTE, 15, @StartDate)
THEN 1
ELSE 0
END) AS New
FROM
tbl_Calls WITH (NOLOCK)
WHERE
cl_StartTime BETWEEN @StartDate AND @EndDate) AS Inners
GROUP BY
New
Run Code Online (Sandbox Code Playgroud)
如果您需要更多详细信息,请告诉我。
这是“数字表”如何真正帮助获得所需结果的经典示例。
本质上,您创建了一个包含所需 15 分钟增量的表,然后加入您的表以获取每 15 分钟增量的总呼叫数。
例如,我对两个表都使用临时表。您可能希望将该#Intervals
表永久化。
创建测试平台,并填充一些示例数据:
USE tempdb;
IF (OBJECT_ID('tempdb..#Calls') IS NOT NULL)
DROP TABLE #Calls;
CREATE TABLE #Calls
(
CallID INT NOT NULL
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, CallStart DATETIME NOT NULL
, CallEnd DATETIME NOT NULL
);
;WITH cte AS
(
SELECT rn = ROW_NUMBER() OVER (ORDER BY o.object_id, o1.object_id)
, rn1 = ROW_NUMBER() OVER (PARTITION BY o.object_id
ORDER BY o1.object_id)
FROM sys.objects o, sys.objects o1
)
INSERT INTO #Calls (CallStart, CallEnd)
SELECT DATEADD(MINUTE, c.rn, DATEADD(DAY, -1, GETDATE()))
, DATEADD(MINUTE, c.rn + c.rn1, DATEADD(DAY, -1, GETDATE()))
FROM cte c;
IF (OBJECT_ID('tempdb..#Intervals') IS NOT NULL)
DROP TABLE #Intervals;
CREATE TABLE #Intervals
(
DateStart DATETIME NOT NULL
, DateEnd DATETIME NOT NULL
);
;WITH cte AS
(
SELECT TOP(35040) /* approx. number of 15 minute intervals in a year */
rn = ROW_NUMBER() OVER (ORDER BY o.object_id, o1.object_id) * 15
FROM sys.objects o
, sys.objects o1
, sys.objects o2
)
INSERT INTO #Intervals (DateStart, DateEnd)
SELECT DATEADD(MINUTE, c.rn, '2015-10-01T00:00:00')
, DATEADD(MINUTE, c.rn + 15, '2015-10-01T00:00:00')
FROM cte c;
Run Code Online (Sandbox Code Playgroud)
显示两个表中的行:
SELECT *
FROM #Intervals i
ORDER BY i.DateStart;
SELECT *
FROM #Calls c
ORDER BY c.CallStart;
Run Code Online (Sandbox Code Playgroud)
连接两个表以获取 15 分钟日期范围之间的呼叫总数:
SELECT i.DateStart
, i.DateEnd
, TotalCalls = COUNT(1)
FROM #Calls c
INNER JOIN #Intervals i ON c.CallStart >= i.DateStart
AND c.CallStart < i.DateEnd
GROUP BY i.DateStart
, i.DateEnd
ORDER BY i.DateStart;
Run Code Online (Sandbox Code Playgroud)
在我的测试平台上,我从三个select
语句中得到以下结果:
查看您对@Thofle 的回答的评论,您似乎希望查看所有时间间隔,即使在给定间隔内没有电话。为此,您可以简单地修改select
查询以使用 aLEFT JOIN
和行COUNT(...)
数Calls
,例如:
SELECT i.DateStart
, i.DateEnd
, TotalCalls = COUNT(c.CallID)
FROM #Intervals i
LEFT JOIN #Calls c
ON i.DateStart <= c.CallStart
AND i.DateEnd > c.CallStart
GROUP BY i.DateStart
, i.DateEnd
ORDER BY i.DateStart;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25198 次 |
最近记录: |