SQL查询按天分组


Answers:


164

如果您使用的是SQL Server,

dateadd(DAY,0, datediff(day,0, created)) 将返回创建的日期

例如,如果销售创建于“ 2009-11-02 06:12:55.000”,则 dateadd(DAY,0, datediff(day,0, created))返回“ 2009-11-02 00:00:00.000”

select sum(amount) as total, dateadd(DAY,0, datediff(day,0, created)) as created
from sales
group by dateadd(DAY,0, datediff(day,0, created))

用这种方法设计还是直接使用DATE并直接在其上分组会更有效吗?
Sinaesthetic

@Sinaesthetic取决于要求。
安华·钱德拉

108

对于SQL Server:

GROUP BY datepart(year,datefield), 
    datepart(month,datefield), 
    datepart(day,datefield)

或更快(来自Q8-Coder):

GROUP BY dateadd(DAY,0, datediff(day,0, created))

对于MySQL:

GROUP BY year(datefield), month(datefield), day(datefield)

或更好(来自Jon Bright):

GROUP BY date(datefield)

对于Oracle:

GROUP BY to_char(datefield, 'yyyy-mm-dd')

或更快(来自IronGoofy):

GROUP BY trunc(created);

对于Informix(Jonathan Leffler撰写):

GROUP BY date_column
GROUP BY EXTEND(datetime_column, YEAR TO DAY)

感谢列出所有不同的语法
CTS_AE

43

如果您使用的是MySQL:

SELECT
    DATE(created) AS saledate,
    SUM(amount)
FROM
    Sales
GROUP BY
    saledate

如果您使用的是MS SQL 2008:

SELECT
    CAST(created AS date) AS saledate,
    SUM(amount)
FROM
    Sales
GROUP BY
    CAST(created AS date)

5
恐怕这些例子将以微秒为单位
-Andomar

安多玛(Andomar),我只是尝试了一种MS SQL(在对语法进行了微小的调整之后)。它在这里按日期愉快地分组。我也没有时间去尝试MySQL,但是我整天都在使用它,我或多或少地确定它也会按日期分组。
乔恩·

@Jon Bright:我的评论是在编辑之前。当前的仍然不正确:日期类型仅在SQL Server 2008中受支持
Andomar

Andomar,由于您不确定我的意思,因此我也刚刚检查了MySQL。它可以完美工作并按日期分组。
乔恩·布赖特

Andomar,至少在按日期或微秒分组时,编辑使结果的功能差异为零。如果只有2008年支持日期时间(我没看过),那不会使答案有误,它仅适用于MS SQL2008。存在区别。
乔恩·

7

实际上这取决于您使用的DBMS,但是在常规SQL中,convert(varchar,DateColumn,101)它将DATETIME格式更改为日期(一天)

所以:

SELECT 
    sum(amount) 
FROM 
    sales 
GROUP BY 
    convert(varchar,created,101)

magix数字101是它转换成的日期格式


2
+1是的是的话,什么101的手段在此说明msdn.microsoft.com/en-us/library/ms187928.aspx
Andomar

7

如果您使用的是SQL Server,则可以将三个计算出的字段添加到表中:

Sales (saleID INT, amount INT, created DATETIME)

ALTER TABLE dbo.Sales
  ADD SaleYear AS YEAR(Created) PERSISTED
ALTER TABLE dbo.Sales
  ADD SaleMonth AS MONTH(Created) PERSISTED
ALTER TABLE dbo.Sales
  ADD SaleDay AS DAY(Created) PERSISTED

现在您可以轻松地按销售的天,月或年分组,排序等:

SELECT SaleDay, SUM(Amount)
FROM dbo.Sales
GROUP BY SaleDay

这些计算出的字段将始终保持最新状态(当“创建的”日期更改时),它们属于表,可以像常规字段一样使用,甚至可以进行索引(如果它们是“ PERSISTED” )-恕我直言,但尚未充分使用的强大功能。

马克


确实是的!如果您需要始终按日,月,年进行报告,则非常有用:-)
marc_s 2009年

2

对于oracle,您可以

group by trunc(created);

因为这会将创建的日期时间截断到前一个午夜。

另一种选择是

group by to_char(created, 'DD.MM.YYYY');

可以达到相同的结果,但可能会更慢,因为它需要类型转换。


这可能是特定于Oracle的,但是非常方便。还有一个trunc(...,'MONTH'),可以快速为您提供每月的第一天,等等
。– Thorsten

2

对于PostgreSQL:

GROUP BY to_char(timestampfield, 'yyyy-mm-dd')

或使用演员表:

GROUP BY timestampfield::date

如果要提高速度,请使用第二个选项并添加索引:

CREATE INDEX tablename_timestampfield_date_idx ON  tablename(date(timestampfield));

-3

使用LINQ

from c in Customers
group c by DbFunctions.TruncateTime(c.CreateTime) into date
orderby date.Key descending
select new  
{
    Value = date.Count().ToString(),
    Name = date.Key.ToString().Substring(0, 10)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.