Sql sorgusunu güne göre gruplandır


135

Tüm satışları listelemek ve toplamı güne göre gruplamak istiyorum.

Sales (saleID INT, amount INT, created DATETIME)

Güncelleştirme SQL Server 2005 kullanıyorum


4
Tarih fonksiyonları SQL lehçelerinde farklı olduğu için hangi veritabanını kullandığınızı belirtmelisiniz.
Guffa

Güne göre gruplama hakkında daha fazla bilgi için buraya bakın. sqlserverlearner.com/2012/group-by-day-with-examples

Yanıtlar:


164

SQL Server kullanıyorsanız,

dateadd(DAY,0, datediff(day,0, created)) oluşturulan günü döndürecek

örneğin, satış '2009-11-02 06: 12: 55.000' tarihinde oluşturulmuşsa, dateadd(DAY,0, datediff(day,0, created))'2009-11-02 00: 00: 00.000' döndür

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))

aklınızdan çıkmasın, bu şekilde tasarlamak mı yoksa sadece DATE'i kullanıp doğrudan üzerinde gruplamak mı daha verimli olur?
Sinaesthetic

@Sinaesthetic gereksinimlere bağlıdır.
Anwar Chandra

108

SQL Server için:

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

veya daha hızlı (Q8-Coder'dan):

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

MySQL için:

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

veya daha iyisi (Jon Bright'tan):

GROUP BY date(datefield)

Oracle için:

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

veya daha hızlı (IronGoofy'den):

GROUP BY trunc(created);

Informix için (Jonathan Leffler):

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

Tüm farklı sözdizimlerini listelediğiniz için teşekkürler
CTS_AE

43

MySQL kullanıyorsanız:

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

MS SQL 2008 kullanıyorsanız:

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

5
Korkarım bu örnekler mikrosaniyeye göre gruplanacak
Andomar

Andomar, MS SQL'i denedim (sözdiziminde küçük bir değişiklik yaptıktan sonra). Burada tarihe göre mutlu bir şekilde gruplar. MySQL'i denemek için de vaktim yok, ancak bunu tüm gün işimde kullanıyorum ve tarihe göre de gruplayacağından aşağı yukarı eminim.
Jon Bright

@Jon Bright: Yorumum bir düzenlemeden önceydi. Şu anki durum hala yanlış: tarih türü yalnızca SQL Server 2008'de destekleniyor
Andomar

Andomar, beni emin olmadığından beri, ben de MySQL'i kontrol ettim. Mükemmel çalışıyor ve tarihe göre gruplar.
Jon Bright

Andomar, düzenleme, en azından tarihe veya mikrosaniyeye göre gruplama ile ilgili olarak sonuçta sıfır işlevsel fark yarattı. Yalnızca 2008 tarih saatini destekliyorsa (bakmadım), bu yanıtı yanlış yapmaz, yalnızca MS SQL 2008 için geçerli olur. Bir fark var.
Jon Bright

7

aslında bu, kullandığınız DBMS'ye bağlıdır, ancak normal SQL'de convert(varchar,DateColumn,101) DATETIME biçimini bugüne kadar değiştirir (bir gün)

yani:

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

büyülü sayı 101, dönüştürüldüğü tarih biçimidir


2
+1 Evet öyle, 101'in anlamı burada açıklanıyor msdn.microsoft.com/en-us/library/ms187928.aspx
Andomar

7

SQL Server kullanıyorsanız, tablonuza üç hesaplanan alan ekleyebilirsiniz:

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

ve şimdi satış gününe, ayına veya yılına göre kolayca gruplayabilir, sıralayabilirsiniz:

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

Bu hesaplanan alanlar her zaman güncel tutulur ("Oluşturulma" tarihiniz değiştiğinde), tablonuzun parçasıdırlar, normal alanlar gibi kullanılabilirler ve hatta dizine alınabilir ("DEVAMLI" ise) ) - tamamen az kullanılan harika bir özellik, IMHO.

üzüm posası


Evet kesinlikle! Her zaman gün, ay, yıl raporlama yapmanız gerekiyorsa oldukça kullanışlıdır :-)
marc_s

2

Oracle için yapabilirsin

group by trunc(created);

çünkü bu, oluşturulan tarih saatini önceki gece yarısına kadar kısaltır.

Başka bir seçenek de

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

aynı sonucu verir, ancak bir tür dönüşümü gerektirdiğinden daha yavaş olabilir.


Bu muhtemelen Oracle'a özgüdür, ancak oldukça kullanışlıdır. Ayrıca size ayın ilk gününü hızlı bir şekilde vermek için bir kesik (..., 'AY') vardır vb.
Thorsten

2

PostgreSQL için:

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

veya cast kullanarak:

GROUP BY timestampfield::date

hız istiyorsanız, ikinci seçeneği kullanın ve bir dizin ekleyin:

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

-3

linq kullan

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)
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.