我试图在我的数据库中查询过去3天内每个用户所做的记录(电话)数量(例如)。
我试图实现以下查询输出:
username 10-11-2014 11-11-2014 12-11-2014
user1 24 25 20
user2 23 20 30
我可以使用以下查询来执行此操作,但对我来说,这似乎是一个非常漫长的方式,我认为我能够使用连接来做到这一点,但我不知道。
SELECT username,
(SELECT count(tblCall.call_id)
FROM tblCall
WHERE tblCall.started_at BETWEEN '2014-11-10 00:00:00' AND
'2014-11-10 23:00:00' AND
tblCall.from_user_id = tblUser.user_id) AS '10-11-2014',
(SELECT count(tblCall.call_id)
FROM tblCall
WHERE tblCall.started_at BETWEEN '2014-11-11 00:00:00' AND
'2014-11-11 23:00:00' AND
tblCall.from_user_id = tblUser.user_id) AS '11-11-2014',
(SELECT count(tblCall.call_id)
FROM tblCall
WHERE tblCall.started_at BETWEEN '2014-11-12 00:00:00' AND
'2014-11-12 23:00:00' AND
tblCall.from_user_id = tblUser.user_id) AS '12-11-2014'
FROM tblUser
WHERE tblUser.can_manage_accounts = '1' AND
tblUser.telephone_ext != '' AND
tblUser.blocked = '0'
GROUP BY tblUser.user_id, tblUser.username
我希望能够指定查询呼叫的日期范围,并让它们每天都返回到新列中。这可能吗?
谢谢!
答案 0 :(得分:2)
试试这个......
SELECT username
,count(CASE WHEN tblCall.started_at BETWEEN '2014-11-10 00:00:00' AND '2014-11-10 23:00:00' THEN tblCall.call_id ELSE NULL END) AS [10-11-2014]
,count(CASE WHEN tblCall.started_at BETWEEN '2014-11-11 00:00:00' AND '2014-11-11 23:00:00' THEN tblCall.call_id ELSE NULL END) AS [11-11-2014]
,count(CASE WHEN tblCall.started_at BETWEEN '2014-11-12 00:00:00' AND '2014-11-12 23:00:00' THEN tblCall.call_id ELSE NULL END) AS [12-11-2014]
FROM tblUser
INNER JOIN tblCall ON tblCall.from_user_id = tblUser.[user_id]
WHERE tblUser.can_manage_accounts = '1'
AND tblUser.telephone_ext != ''
AND tblUser.blocked = '0'
GROUP BY tblUser.username
CREATE TABLE TEST_TABLE(UserName VARCHAR(100), started_at DATETIME)
GO
INSERT INTO TEST_TABLE VALUES
('Mark' , '2014-11-13 23:59:59.997'),('Jane' , '2014-11-13 23:59:59.997'),('Sam' , '2014-11-13 23:59:59.997'),
('Mark' , '2014-11-13 23:59:59.997'),('Jane' , '2014-11-13 23:59:59.997'),('Sam' , '2014-11-13 23:59:59.997'),
('Holly' ,'2014-11-12 23:59:59.997'),('Sally' ,'2014-11-12 23:59:59.997'),('Mandy' ,'2014-11-12 23:59:59.997'),
('Holly' ,'2014-11-12 23:59:59.997'),('Sally' ,'2014-11-12 23:59:59.997'),('John' ,'2014-11-11 23:59:59.997'),
('James' ,'2014-11-11 23:59:59.997'),('John' ,'2014-11-11 23:59:59.997'),('James' ,'2014-11-11 23:59:59.997'),
('Josh' ,'2014-11-10 23:59:59.997'),('Jamie' ,'2014-11-10 23:59:59.997')
GO
DECLARE @Range_Start DATE = '2014-11-11'
DECLARE @Range_End DATE = '2014-11-13'
DECLARE @Date_Columns NVARCHAR(MAX);
DECLARE @Sql NVARCHAR(MAX);
SELECT @Date_Columns = STUFF(( SELECT DISTINCT ', ' + QUOTENAME(CONVERT(VARCHAR(10), started_at, 120))
FROM TEST_TABLE
WHERE CAST(started_at AS DATE) >= @Range_Start
AND CAST(started_at AS DATE) <= @Range_End
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,2,'')
SET @Sql = N' SELECT *
FROM (
SELECT UserName, COUNT(*) AS Total, CONVERT(VARCHAR(10), started_at, 120) AS started_at
FROM TEST_TABLE
WHERE CAST(started_at AS DATE) >= @Range_Start
AND CAST(started_at AS DATE) <= @Range_End
GROUP BY UserName, CONVERT(VARCHAR(10), started_at, 120)
) t
PIVOT ( SUM(Total)
FOR started_at
IN (' + @Date_Columns + ')
)p '
Execute sp_executesql @Sql
,N'@Range_Start DATE, @Range_End DATE'
,@Range_Start
,@Range_End
╔══════════╦════════════╦════════════╦════════════╗
║ UserName ║ 2014-11-11 ║ 2014-11-12 ║ 2014-11-13 ║
╠══════════╬════════════╬════════════╬════════════╣
║ Holly ║ NULL ║ 2 ║ NULL ║
║ James ║ 2 ║ NULL ║ NULL ║
║ Jane ║ NULL ║ NULL ║ 2 ║
║ John ║ 2 ║ NULL ║ NULL ║
║ Mandy ║ NULL ║ 1 ║ NULL ║
║ Mark ║ NULL ║ NULL ║ 2 ║
║ Sally ║ NULL ║ 2 ║ NULL ║
║ Sam ║ NULL ║ NULL ║ 2 ║
╚══════════╩════════════╩════════════╩════════════╝
答案 1 :(得分:0)
您需要使用Dynamic Sql
DECLARE @cols VARCHAR(max)='',
@sql NVARCHAR(max),
@start_date DATETIME='2009-08-25 00:00:00',--start date
@end_date DATETIME='2009-09-02 00:00:00'--end date
SELECT @cols += ',[' + CONVERT(VARCHAR(30), started_at, 102)+ ']'
FROM (SELECT DISTINCT CONVERT(DATE, started_at) started_at
FROM #tblCall
WHERE started_at BETWEEN @start_date AND @end_date) A
SELECT @cols = RIGHT(@cols, Len(@cols) - 1)
SET @sql='SELECT *
FROM (SELECT Count(call_id) cnt,
CONVERT(DATE, started_at) started_at,
userid
FROM #tblCall where started_at between '''+ CONVERT(VARCHAR(30), @start_date, 102)+ ''' and '''
+ CONVERT(VARCHAR(30), @end_date, 102)
+ ''' GROUP BY userid,
CONVERT(DATE, started_at)) A
PIVOT (Max(cnt)
FOR started_at IN (' + @cols + ')) piv'
EXEC Sp_executesql @sql