Sql permintaan ke Grup berdasarkan hari

134

Saya ingin mendaftar semua penjualan, dan mengelompokkan jumlah berdasarkan hari.

Sales (saleID INT, amount INT, created DATETIME)

Pembaruan Saya menggunakan SQL Server 2005

mrblah
sumber
4
Anda harus menentukan basis data apa yang Anda gunakan, karena fungsi tanggal berbeda dalam dialek SQL-nya.
Guffa
Lihat di sini untuk info lebih lanjut tentang pengelompokan berdasarkan hari. sqlserverlearner.com/2012/group-by-day-with-examples

Jawaban:

164

jika Anda menggunakan SQL Server,

dateadd(DAY,0, datediff(day,0, created)) akan mengembalikan hari yang dibuat

misalnya, jika penjualan dibuat pada '2009-11-02 06: 12: 55.000', dateadd(DAY,0, datediff(day,0, created))kembalikan '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))
Anwar Chandra
sumber
dari atas kepala Anda, apakah akan lebih efisien untuk mendesain dengan cara ini atau menggunakan DATE dan mengelompokkannya secara langsung?
Sinaesthetic
@Sestetika yang tergantung pada persyaratan.
Anwar Chandra
108

Untuk SQL Server:

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

atau lebih cepat (dari Q8-Coder):

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

Untuk MySQL:

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

atau lebih baik (dari Jon Bright):

GROUP BY date(datefield)

Untuk Oracle:

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

atau lebih cepat (dari IronGoofy):

GROUP BY trunc(created);

For Informix (oleh Jonathan Leffler):

GROUP BY date_column
GROUP BY EXTEND(datetime_column, YEAR TO DAY)
Andomar
sumber
Terima kasih telah mendaftar semua sintaks yang berbeda
CTS_AE
43

Jika Anda menggunakan MySQL:

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

Jika Anda menggunakan MS SQL 2008:

SELECT
    CAST(created AS date) AS saledate,
    SUM(amount)
FROM
    Sales
GROUP BY
    CAST(created AS date)
Jon Bright
sumber
5
Saya khawatir contoh-contoh ini akan dikelompokkan berdasarkan mikrodetik
Andomar
Andomar, saya baru saja mencoba yang MS SQL (setelah tweak kecil ke sintaks). Dengan senang hati kelompok berdasarkan tanggal di sini. Saya tidak punya waktu untuk pergi dan mencoba MySQL juga, tetapi saya menggunakannya sepanjang hari dalam pekerjaan saya dan saya kurang lebih yakin bahwa itu akan dikelompokkan berdasarkan tanggal juga.
Jon Bright
@ Jon Bright: Komentar saya sebelum diedit. Yang saat ini masih salah: tipe tanggal hanya didukung di SQL Server 2008
Andomar
Andomar, karena Anda membuat saya tidak yakin, saya baru saja dan memeriksa satu MySQL juga. Ini berfungsi dengan baik dan dikelompokkan berdasarkan tanggal.
Jon Bright
Andomar, hasil edit tidak membuat perbedaan fungsional pada hasilnya, setidaknya terkait dengan pengelompokan berdasarkan tanggal atau mikrodetik. Jika hanya 2008 mendukung waktu tanggal (saya belum melihat), itu tidak membuat jawaban salah, itu membuatnya hanya berlaku untuk MS SQL 2008. Ada perbedaan.
Jon Bright
7

sebenarnya ini tergantung pada DBMS apa yang Anda gunakan tetapi dalam SQL biasa convert(varchar,DateColumn,101)akan mengubah format DATETIME ke tanggal (satu hari)

begitu:

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

angka magix 101adalah format tanggal yang diubahnya

Yopefonic
sumber
2
+1 Ya, benar, apa artinya 101 dijelaskan di sini msdn.microsoft.com/en-us/library/ms187928.aspx
Andomar
7

Jika Anda menggunakan SQL Server, Anda bisa menambahkan tiga bidang terhitung ke tabel Anda:

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

dan sekarang Anda dapat dengan mudah mengelompokkan berdasarkan, memesan berdasarkan dll. berdasarkan hari, bulan atau tahun penjualan:

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

Bidang-bidang yang dihitung akan selalu tetap terbaru (ketika tanggal "Dibuat" Anda berubah), mereka adalah bagian dari tabel Anda, bidang tersebut dapat digunakan seperti bidang biasa, dan bahkan dapat diindeks (jika "TERTENTU" ) - fitur hebat yang benar-benar kurang dimanfaatkan, IMHO.

Marc

marc_s
sumber
Ya memang! Cukup berguna jika Anda perlu melaporkan pada hari, bulan, tahun sepanjang waktu :-)
marc_s
2

Untuk oracle kamu bisa

group by trunc(created);

karena ini memotong datetime yang dibuat ke tengah malam sebelumnya.

Pilihan lain adalah

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

yang mencapai hasil yang sama, tetapi mungkin lebih lambat karena memerlukan konversi jenis.

Thorsten
sumber
Itu mungkin cukup spesifik Oracle, tapi cukup berguna. Ada juga trunc (..., 'BULAN') untuk dengan cepat memberi Anda hari pertama bulan dll.
Thorsten
2

Untuk PostgreSQL:

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

atau menggunakan gips:

GROUP BY timestampfield::date

jika Anda ingin kecepatan, gunakan opsi kedua dan tambahkan indeks:

CREATE INDEX tablename_timestampfield_date_idx ON  tablename(date(timestampfield));
Francisco Valdez
sumber
-3

gunakan 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)
}
liubinqiang
sumber