Sql запит до групи по днях


134

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

Sales (saleID INT, amount INT, created DATETIME)

Оновлення Я використовую SQL Server 2005


4
Ви повинні вказати, яку базу даних ви використовуєте, оскільки функції дат відрізняються в діалектах SQL.
Гуффа

Тут можна дізнатися більше про групування за днями. sqlserverlearner.com/2012/group-by-day-with-examples

Відповіді:


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 та групувати його безпосередньо?
Сінестетик

@ Синестетичне, що залежить від вимог.
Анвар Чандра

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)

або краще (від Джон Брайт):

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)

Дякуємо, що перерахували всі різні синтаксиси
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, я просто спробував MS SQL (після незначного підключення до синтаксису). Тут радісно гуртуються за датами. У мене теж немає часу, щоб спробувати MySQL, але я цілий день використовую його в своїй щоденній роботі, і я більш-менш впевнений, що він також збирається групуватися за датою.
Джон Брайт

@Jon Bright: Мій коментар був до редагування. Поточний все ще невірний: тип дати підтримується лише у SQL Server 2008
Andomar

Andomar, оскільки ви не впевнені, я теж перевіряв MySQL. Він прекрасно працює і групується за датою.
Джон Брайт

Andomar, редагування внесло нульову функціональну різницю в результат, принаймні, що стосується групування за датою або мікросекундами. Якщо тільки 2008 підтримує час дати (я не дивився), це не робить відповідь неправильною, вона застосовує лише до MS SQL 2008. Є різниця.
Джон Брайт

7

насправді це залежить від того, які СУБД ви використовуєте, але в звичайному 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

Ці обчислені поля завжди будуть постійно оновлюватися (коли змінено дату "Створено"), вони є частиною вашої таблиці, вони можуть використовуватися як звичайні поля, і навіть можуть бути індексовані (якщо вони "ПЕРСПЕКТИВНІ" ) - відмінна функція, яка повністю використовується, IMHO.

Марк


Так, справді! Досить корисно, якщо вам потрібно весь час звітувати про день, місяць, рік :-)
marc_s

2

Для оракул можна

group by trunc(created);

оскільки це скорочує створене дату до попередньої півночі.

Інший варіант - це

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

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


Це, мабуть, досить специфічно для Oracle, але цілком зручно. Існує також обрізка (..., "МІСЯЦЬ"), щоб швидко надати вам перший день місяця тощо
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)
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.