2009-11-01 3 views
85

Я хочу перечислить все продажи и сгруппировать сумму за день.Sql запрос в группу за день

Sales (saleID INT, amount INT, created DATETIME) 

Update Я использую SQL Server 2005

+4

Вы должны указать, какую базу данных вы используете, поскольку функции даты отличаются от их диалектов SQL. На картинку, посыл по телефону: – Guffa

+0

См. Полный профиль http://sqlserverlearner.com/2012/group-by-day-with-examples – 2012-05-02 08:33:49

ответ

113

, если вы используете SQL Server,

dateadd(DAY,0, datediff(day,0, created)) возвратит день созданный

, например, если продажа создано on '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)) 
+0

с верхней части головы, было бы более целесообразным спроектировать этот способ или просто использовать DATE и сгруппировать на нем напрямую? – Sinaesthetic

+0

@ Синестетика, которая зависит от требований. –

21

Если вы используете 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) AS saledate 
+2

Я боюсь, что эти примеры будут группироваться по микросекундам – Andomar

+0

Andomar, я просто попробовал MS SQL один (после незначительной настройки синтаксиса). Он счастливо группируется по дате здесь. У меня нет времени, чтобы пойти и попробовать MySQL тоже, но я использую его весь день в моей дневной работе, и я более или менее уверен, что он будет группироваться по дате. –

+0

@Jon Bright: Мой комментарий был до редактирования. Текущий по-прежнему неверен: тип даты поддерживается только в SQL Server 2008 – Andomar

2

Для оракула вы можете

group by trunc(created); 

как это обрезает создал дату и время до полуночи.

Другого варианта заключается в

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

, который достигает тот же результат, но может быть медленнее, так как она требует преобразования типа.

+1

+1 Интересный trunc()! – Andomar

+0

Это, вероятно, довольно специфичный для Oracle, но довольно удобный. Существует также trunc (..., «MONTH»), чтобы быстро дать вам первый день месяца и т. Д. – Thorsten

71

Для 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 (Джонатан Леффлера):

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

Спасибо, что перечислены все различные синтаксисы. –

4

на самом деле это зависит от того, что СУБД, что вы используете но в обычном SQL convert(varchar,DateColumn,101) изменит формат DATETIME на сегодняшний день (один день)

так:

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

MAGIX номер 101 является то, что формат даты он преобразуется в

+1

+1 Да, это так, то, что здесь описано 101 http://msdn.microsoft.com/en-us/library/ms187928.aspx – Andomar

6

Если вы используете 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») - отличная функция, которая полностью недоиспользована, ИМХО.

Марк

+0

+1 Это позволит вам создать индекс в дате части :) – Andomar

+0

Да, действительно! Весьма полезно, если вам нужно постоянно сообщать о дне, месяце, году :-) –

+0

как насчет ДНЯ (создан)? – mrblah

0

Для PostgreSQL:

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

или с использованием литой:

GROUP BY timestampfield::date 

если вы хотите скорость, используйте второй вариант и добавить индекс:

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

использовать 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) 
} 
Смежные вопросы