我最近在SQL中构建了一个查询,我可以用来查看我们的付款日志,并找出一段时间内每小时的平均付款次数。我确信有第三方报告应用程序更适合做我正在尝试的计算类型,但只是为了好玩,我很想知道你们可能使用的其他方法(在T-SQL)获取我正在寻找的数据。我知道这是一个愚蠢的问题,所以如果你投票给我,我不会被冒犯。但是,对于像我这样无聊的其他人,请随意发布您的其他解决方案。
该表设置有[CreateDate]列,该列是付款过帐到帐户时的DATETIME值。我用这个来确定他们付款的时间。
CREATE TABLE #TempTimes
(
[Time] DATETIME,
)
DECLARE @numDays INT
SET @numDays = 10
DECLARE @time DATETIME
SET @time = DATEADD(dd, DATEDIFF(dd, 0, GETDATE() - @numDays), 0)
WHILE @time < GETDATE()
BEGIN
INSERT #TempTimes
VALUES (@time)
SET @time = DATEADD(hour, 1, @time)
END
GO
/*
I have to join in a table with all of the hours for the time span I'm querying against,
because otherwise, the AVG function won't calculate in the hours where no payments were made.
*/
SELECT DATEPART(hour, [Time]) [Hour], AVG(CAST([Count] AS DECIMAL)) [Average]
FROM
(
SELECT [Time], CASE WHEN [Count] IS NULL THEN 0 ELSE [Count] END [Count]
FROM #TempTimes tt
LEFT JOIN
(
SELECT DATEADD(hour, DATEDIFF(hour, 0, [CreateDate]), 0) [hour], COUNT(*) [Count]
FROM [dbo].[PaymentLog]
GROUP BY DATEADD(hour, DATEDIFF(hour, 0, [CreateDate]), 0)
) t1 ON t1.[hour] = tt.[time]
) t2
GROUP BY DATEPART(hour, tt.[Time])
GO
DROP TABLE #TempTimes
GO
CJ
答案 0 :(得分:1)
您正在使用与临时表的连接从主表中过滤的IIUC。
为什么不删除连接并只使用where子句?如果您想强制显示所有时间,请在之后加入,或使用某种联合。
答案 1 :(得分:1)
我认为这是一个相当漂亮的方法。它避免使用Hours表(或像你正在使用的临时表)。缺点是它只显示付款的小时值。让前端全部放入0。 :)
CREATE TABLE dbo.Payments
(
payment_id INT IDENTITY NOT NULL,
create_date DATETIME NOT NULL,
CONSTRAINT PK_Payments PRIMARY KEY CLUSTERED (payment_id)
)
GO
INSERT INTO dbo.Payments (create_date)
SELECT '2009-02-25 12:00:00.000' UNION
SELECT '2009-02-25 12:45:00.000' UNION
SELECT '2009-02-25 12:30:00.000' UNION
SELECT '2009-02-25 13:10:00.000' UNION
SELECT '2009-02-25 13:22:00.000' UNION
SELECT '2009-02-25 14:09:00.000' UNION
SELECT '2009-02-25 14:40:00.000'
GO
SELECT
CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME),
COUNT(T3.payment_id) + 1
FROM
dbo.Payments T1
LEFT OUTER JOIN dbo.Payments T2 ON
T2.create_date >= CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME) AND
T2.create_date < T1.create_date
LEFT OUTER JOIN dbo.Payments T3 ON
T3.create_date >= T1.create_date AND
T3.create_date < DATEADD(hh, 1, CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME)) AND
T3.payment_id <> T1.payment_id
WHERE
T2.payment_id IS NULL
GROUP BY
CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME)
GO