แบบสอบถาม SQL เพื่อจัดกลุ่มตามวัน


137

ฉันต้องการแสดงรายการขายทั้งหมดและจัดกลุ่มผลรวมตามวัน

Sales (saleID INT, amount INT, created DATETIME)

หมายเหตุ: ฉันใช้ SQL Server 2005


4
คุณต้องระบุฐานข้อมูลที่คุณใช้เนื่องจากฟังก์ชันวันที่แตกต่างกันในภาษา SQL
Guffa

ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดกลุ่มตามวันได้ที่นี่ sqlserverlearner.com/2012/group-by-day-with-examples

คำตอบ:


168

ถ้าคุณใช้ 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 และจัดกลุ่มโดยตรง
Sinaesthetic

@Sinaesthetic ที่ขึ้นอยู่กับความต้องการ
Anwar Chandra

114

สำหรับ 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 (โดย Jonathan Leffler):

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

ขอขอบคุณที่แสดงรายการไวยากรณ์ที่แตกต่างกันทั้งหมด
CTS_AE

50

หากคุณใช้ 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)

6
ฉันเกรงว่าตัวอย่างเหล่านี้จะจัดกลุ่มตามไมโครวินาที
Andomar

Andomar ฉันเพิ่งลอง MS SQL หนึ่ง (หลังจากปรับแต่งไวยากรณ์เล็กน้อย) จัดกลุ่มตามวันที่ที่นี่อย่างมีความสุข ฉันไม่มีเวลาไปลองใช้ MySQL ด้วย แต่ฉันใช้มันทั้งวันในงานประจำวันของฉันและฉันก็มั่นใจไม่มากก็น้อยว่าจะจัดกลุ่มตามวันที่ด้วย
Jon Bright

@ จอนไบรท์: ความคิดเห็นของฉันเกิดขึ้นก่อนการแก้ไข ปัจจุบันยังไม่ถูกต้อง: ประเภทวันที่ได้รับการสนับสนุนเฉพาะใน SQL Server 2008
Andomar

Andomar เนื่องจากคุณทำให้ฉันไม่แน่ใจฉันก็เพิ่งได้รับและตรวจสอบ MySQL ด้วย ทำงานได้อย่างสมบูรณ์แบบและจัดกลุ่มตามวันที่
Jon Bright

Andomar การแก้ไขทำให้ผลการทำงานแตกต่างกันเป็นศูนย์อย่างน้อยก็เกี่ยวข้องกับการจัดกลุ่มตามวันที่หรือไมโครวินาที ถ้าเฉพาะ 2008 รองรับวันเวลา (ฉันไม่ได้ดู) นั่นไม่ได้ทำให้คำตอบไม่ถูกต้องมันทำให้ใช้กับ MS SQL 2008 เท่านั้นมีความแตกต่าง
Jon Bright

7

จริงๆแล้วสิ่งนี้ขึ้นอยู่กับ DBMS ที่คุณใช้ แต่ใน 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

สำหรับ Oracle คุณสามารถทำได้

group by trunc(created);

เนื่องจากจะตัดวันที่และเวลาที่สร้างไว้ให้เหลือเที่ยงคืนก่อนหน้า

อีกทางเลือกหนึ่งคือ

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

ซึ่งได้ผลลัพธ์เดียวกัน แต่อาจช้ากว่าเนื่องจากต้องมีการแปลงประเภท


นั่นอาจค่อนข้างเฉพาะของ Oracle แต่ค่อนข้างมีประโยชน์ นอกจากนี้ยังมี trunc (... , 'MONTH') เพื่อให้คุณทราบวันแรกของเดือนอย่างรวดเร็วเป็นต้น
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)
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.