SQL group by day, with count

66,028

Solution 1

I like this approach in (MS SQL):

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

Solution 2

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

Depending on the dialect of SQL you're using, you may have to change the CAST to something else. The expression should convert the LogDate to a date-only value.

Also, if you say "different refundId" because there could be repeated values of refundId that you only want to count once, use count(DISTINCT refundId)

Solution 3

What database vendor are you using? Whichever it is, replace the "DateOnly(LogDate)" in the following with the appropriate construict to extract the date portion (strip off the time) from the logdate column value and then try this:

Select [DateOnly(LogDate)], Count Distinct RefundId
From RefundProcessLog
Group By [DateOnly(LogDate)]

In Sql server, for e.g., the appropriate construct would be:

Select DateAdd(day, 0, DateDiff(day, 0, LogDate)), Count(Distinct RefundId)
From RefundProcessLog
Group By DateAdd(day, 0, DateDiff(day, 0, LogDate))

Solution 4

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

"DateOnly" is specific to your SQL database, which you haven't specified.

For SQL Server you could use DateAdd(dd,0, DateDiff(dd,0,LogDate)) for "DateOnly"

Solution 5

SQL Server 2008 introduced the date datatype which makes the following possible:

select convert(date, LogDate),
      ,count(refundid) AS 'refunds'
  from RefundProcessing
group by convert(date,LogDate)
order by convert(date,LogDate)
Share:
66,028
Chris McCall
Author by

Chris McCall

The rest of my face does not appear in this textbox. Sorry!

Updated on January 18, 2020

Comments

  • Chris McCall
    Chris McCall over 4 years

    I've got a log table in SQL Server that looks like this:

    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
    

    What I want is a list of results that represents how many different refundids were processed each day, throwing out any NULLs.

    What SQL would I need to write to produce these results?

  • Steve Kass
    Steve Kass over 14 years
    This won't work. It will return a row with a count for each distinct value of refundid, which is not what's wanted.
  • James
    James almost 7 years
    The performance of this should be far better than the accepted solution, which involves a string conversion.
  • Fonnae
    Fonnae about 5 years
    @James Agree about the performance versus string conversion. But do you (or anyone) know about performance versus the solution from charles-bretana that uses DateAdd(day, 0, DateDiff(day, 0, LogDate))
  • James
    James about 5 years
    @Fonnae, I haven't measured, but I would expect this to be slightly faster than that other answer because that's doing some generic date manipulations (which are probably slower than this CAST), and I'm pretty sure those operations result in a full DATETIME with midnight as the time, whereas this solution does the grouping using the smaller DATE type, which should be faster to work with.