按天分组SQL,附带计数

23

我在SQL Server中有一个日志表,看起来像这样:

CREATE TABLE [dbo].[RefundProcessLog](
 [LogId] [bigint] IDENTITY(1,1) NOT NULL,
 [LogDate] [datetime] NOT NULL,
 [LogType] [varchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
 [RefundId] [int] NULL,
 [RefundTypeId] [smallint] NULL,
 [LogMessage] [varchar](1000) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
 [LoggedBy] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
 CONSTRAINT [PK_RefundProcessLog] PRIMARY KEY CLUSTERED 
(
 [LogId] ASC
) ON [PRIMARY]
) ON [PRIMARY]

GO
我想要一个结果列表,表示每天处理了多少个不同的refundid,排除任何NULL值。
我需要编写什么SQL语句才能生成这些结果?
7个回答

51

我喜欢这种在(MS SQL)中的方法:

SELECT 
  Convert(char(8), LogDate, 112),
  count(distinct RefundId)
FROM RefundProcessing
GROUP BY Convert(char(8), LogDate, 112)

22
select cast(LogDate as date) as LogDate, count(refundId) as refundCount
from yourTable
group by cast(LogDate as date)

根据你所使用的SQL方言,你可能需要将CAST更改为其他内容。该表达式应将LogDate转换为仅日期值。

此外,如果你要说“不同的refundId”,因为refundId可能有重复的值,你只想计数一次,请使用count(DISTINCT refundId)。


1
这个程序的性能应该比涉及字符串转换的已接受解决方案要好得多。 - James
@James 对于性能与字符串转换的问题我同意。但是你(或任何人)是否了解 charles-bretana 的解决方案使用 DateAdd(day, 0, DateDiff(day, 0, LogDate)) 的性能如何? - Fonnae
@Fonnae,我没有测量过,但我预计这个答案会比另一个答案稍微快一些,因为那个答案执行了一些通用的日期操作(这些操作可能比这个CAST慢),而且我很确定这些操作会生成一个完整的DATETIME,时间为午夜,而这个解决方案使用较小的DATE类型进行分组,应该更快速地处理。 - James

8
你使用的数据库供应商是什么?无论是哪一个,都请用适当的构造替换以下的"DateOnly(LogDate)",以从logdate列值中提取日期部分(去掉时间),然后尝试此操作:
Select [DateOnly(LogDate)], Count Distinct RefundId
From RefundProcessLog
Group By [DateOnly(LogDate)]

在SQL Server中,例如,适当的构造应该是:
Select DateAdd(day, 0, DateDiff(day, 0, LogDate)), Count(Distinct RefundId)
From RefundProcessLog
Group By DateAdd(day, 0, DateDiff(day, 0, LogDate))

1
SELECT COUNT(RefundId), DateOnly(LogDate) LoggingDate
FROM RefundProcessLog
GROUP BY DateOnly(LogDate)

"

\"DateOnly\"是特定于您的SQL数据库,而您尚未指定。

对于SQL Server,您可以使用DateAdd(dd,0, DateDiff(dd,0,LogDate))来获取\"DateOnly\"。

"

您可能想在结果集中包含日期。按照当前的写法,这将给出refundIds的数量,但是将无法知道每个数字出现在哪一天。 - Steve Kass

1

SQL Server 2008 引入了 date 数据类型,使得以下操作成为可能:

select convert(date, LogDate),
      ,count(refundid) AS 'refunds'
  from RefundProcessing
group by convert(date,LogDate)
order by convert(date,LogDate)

0
在 SQL Server 中,它会是类似这样的东西:
select datepart(YEAR, [LogDate]), datepart(MONTH, [LogDate]), datepart(DAY, [LogDate]), count(refundid) as [Count]
from [RefundProcessing]
group by datepart(YEAR, [LogDate]), datepart(MONTH, [LogDate]), datepart(DAY, [LogDate])

-1
Select count(*), LogDate, refundid from RefundProcessLog
where refundid is not null
group by LogDate, refundid

编辑:

如果您不想按退款拆分,也可以删除RefundID。


这样做不行。它会返回一个包含每个refundid不同值计数的行,这不是想要的结果。 - Steve Kass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接