Truy vấn Sql vào nhóm theo ngày


134

Tôi muốn liệt kê tất cả doanh số, và nhóm tổng số theo ngày.

Sales (saleID INT, amount INT, created DATETIME)

Cập nhật Tôi đang sử dụng SQL Server 2005


4
Bạn phải xác định cơ sở dữ liệu nào bạn đang sử dụng, vì các hàm ngày khác nhau trong các phương ngữ SQL của chúng.
Guffa

Nhìn vào đây để biết thêm thông tin về nhóm theo ngày. sqlserverlearner.com/2012/group-by-day-with-examples

Câu trả lời:


164

nếu bạn đang sử dụng SQL Server,

dateadd(DAY,0, datediff(day,0, created)) sẽ trả lại ngày đã tạo

ví dụ: nếu việc bán hàng được tạo vào ' dateadd(DAY,0, datediff(day,0, created))2009-11 / 02 06: 12: 55.000', hãy trả lại '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))

ra khỏi đỉnh đầu của bạn, nó sẽ hiệu quả hơn khi thiết kế theo cách này hay chỉ sử dụng DATE và nhóm trực tiếp trên đó?
Trang web thẩm mỹ

@ Thẩm mỹ mà phụ thuộc vào yêu cầu.
Anwar Chandra

108

Đối với máy chủ SQL:

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

hoặc nhanh hơn (từ Q8-Coder):

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

Đối với MySQL:

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

hoặc tốt hơn (từ Jon Bright):

GROUP BY date(datefield)

Đối với Oracle:

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

hoặc nhanh hơn (từ IronGaggery):

GROUP BY trunc(created);

Đối với Informix (của Jonathan Leffler):

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

Cảm ơn vì đã liệt kê tất cả các cú pháp khác nhau
CTS_AE

43

Nếu bạn đang sử dụng MySQL:

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

Nếu bạn đang sử dụng MS SQL 2008:

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

5
Tôi e rằng những ví dụ này sẽ được nhóm theo micrô giây
Andomar

Andomar, tôi vừa thử MS SQL (sau một cú chỉnh nhỏ theo cú pháp). Nó hạnh phúc nhóm theo ngày ở đây. Tôi cũng không có thời gian để đi thử MySQL, nhưng tôi sử dụng nó cả ngày trong công việc hàng ngày của mình và tôi ít nhiều chắc chắn rằng nó cũng sẽ được nhóm theo ngày.
Jon Sáng

@Jon Bright: Nhận xét của tôi là trước khi chỉnh sửa. Kiểu hiện tại vẫn không chính xác: loại ngày chỉ được hỗ trợ trong SQL Server 2008
Andomar

Andomar, vì bạn làm tôi không chắc chắn, tôi cũng đã từng và kiểm tra MySQL. Nó hoạt động hoàn hảo và nhóm theo ngày.
Jon Sáng

Andomar, bản chỉnh sửa đã tạo ra sự khác biệt về chức năng đối với kết quả, ít nhất là mối quan tâm nhóm theo ngày hoặc micro giây. Nếu chỉ có năm 2008 hỗ trợ thời gian ngày (tôi chưa xem), điều đó không làm cho câu trả lời không chính xác, thì nó chỉ áp dụng cho MS SQL 2008. Có một sự khác biệt.
Jon Sáng

7

thực tế điều này phụ thuộc vào DBMS bạn đang sử dụng nhưng trong SQL thông thường convert(varchar,DateColumn,101)sẽ thay đổi định dạng DATETIME thành ngày (một ngày)

vì thế:

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

số magix 101là định dạng ngày được chuyển đổi thành


2
+1 Đúng vậy, ý nghĩa của 101 được giải thích ở đây msdn.microsoft.com/en-us/l Library / ms187928.aspx
Andomar

7

Nếu bạn đang sử dụng SQL Server, bạn có thể thêm ba trường được tính vào bảng của mình:

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

và bây giờ bạn có thể dễ dàng nhóm theo, đặt hàng theo vv theo ngày, tháng hoặc năm bán hàng:

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

Các trường được tính toán đó sẽ luôn được cập nhật (khi ngày "Đã tạo" của bạn thay đổi), chúng là một phần của bảng của bạn, chúng có thể được sử dụng giống như các trường thông thường và thậm chí có thể được lập chỉ mục (nếu chúng được "BỊ" ) - tính năng tuyệt vời mà hoàn toàn không được sử dụng, IMHO.

Marc


Vâng thực sự! Khá hữu ích nếu bạn cần báo cáo vào ngày, tháng, năm mọi lúc :-)
marc_s

2

Đối với nhà tiên tri bạn có thể

group by trunc(created);

vì điều này cắt thời gian được tạo ra vào nửa đêm trước.

Một lựa chọn khác là

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

đạt được kết quả tương tự, nhưng có thể chậm hơn vì nó yêu cầu chuyển đổi loại.


Điều đó có lẽ khá đặc trưng của Oracle, nhưng khá tiện dụng. Ngoài ra còn có một trunc (..., 'MONTH') để nhanh chóng cung cấp cho bạn ngày đầu tiên của tháng, v.v.
Thorsten

2

Đối với PostgreSQL:

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

hoặc sử dụng diễn viên:

GROUP BY timestampfield::date

nếu bạn muốn tốc độ, sử dụng tùy chọn thứ hai và thêm chỉ mục:

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

-3

sử dụng 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)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.