簡體   English   中英

MySQL 按日/月/年查詢GROUP

[英]MySQL Query GROUP BY day / month / year

是否可以進行一個簡單的查詢來計算我在確定的時間段(如年、月或日)中有多少條記錄,具有TIMESTAMP字段,如:

SELECT COUNT(id)
FROM stats
WHERE record_date.YEAR = 2009
GROUP BY record_date.YEAR

甚至:

SELECT COUNT(id)
FROM stats
GROUP BY record_date.YEAR, record_date.MONTH

每月統計一次。

謝謝!

GROUP BY YEAR(record_date), MONTH(record_date)

查看 MySQL 中的日期和時間函數

GROUP BY DATE_FORMAT(record_date, '%Y%m')

注意(主要是針對潛在的反對者)。 目前,這可能不如其他建議有效。 盡管如此,我還是把它作為一個替代方案,它也可以用來了解其他解決方案的速度有多快。 (因為在看到差異之前,您無法真正區分快與慢。)此外,隨着時間的推移,可以在優化方面對 MySQL 的引擎進行更改,以便在某些情況下(也許不是這樣)遙遠的)點在未來,變得與大多數其他人在效率上相當。

試試這個

SELECT COUNT(id)
FROM stats
GROUP BY EXTRACT(YEAR_MONTH FROM record_date)

EXTRACT(unit FROM date)函數更好,因為使用較少的分組並且該函數返回一個數字值。

分組時的比較條件將比 DATE_FORMAT 函數(返回字符串值)更快。 嘗試使用為 SQL 比較條件(WHERE、HAVING、ORDER BY、GROUP BY)返回非字符串值的函數|字段。

我嘗試使用上面的“WHERE”語句,我認為它是正確的,因為沒有人糾正它,但我錯了; 經過一番搜索,我發現這是 WHERE 語句的正確公式,因此代碼變成了這樣:

SELECT COUNT(id)  
FROM stats  
WHERE YEAR(record_date) = 2009  
GROUP BY MONTH(record_date)

如果你搜索了幾年,還想按月分組,我建議:

版本#1:

SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY DATE_FORMAT(record_date, '%Y%m')

版本#2 (更高效)

SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY YEAR(record_date)*100 + MONTH(record_date)

我在一個有 1,357,918 行 ( ) 的大表上比較了這些版本,第二個版本似乎有更好的結果。

version1 (平均執行 10 次) :1.404 秒
version2 (平均執行 10 次) :0.780 秒

(添加了SQL_NO_CACHE鍵以防止 MySQL 對查詢進行緩存。)

如果要過濾特定年份(例如 2000 年)的記錄,請像這樣優化WHERE子句:

SELECT MONTH(date_column), COUNT(*)
FROM date_table
WHERE date_column >= '2000-01-01' AND date_column < '2001-01-01'
GROUP BY MONTH(date_column)
-- average 0.016 sec.

代替:

WHERE YEAR(date_column) = 2000
-- average 0.132 sec.

結果是針對包含 300k 行和日期列索引的表生成的。

至於GROUP BY子句,我針對上述表格測試了三個變體; 結果如下:

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY YEAR(date_column), MONTH(date_column)
-- codelogic
-- average 0.250 sec.

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY DATE_FORMAT(date_column, '%Y%m')
-- Andriy M
-- average 0.468 sec.

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY EXTRACT(YEAR_MONTH FROM date_column)
-- fu-chi
-- average 0.203 sec.

最后一位是贏家。

如果要在 MySQL 中按日期分組,請使用以下代碼:

 SELECT COUNT(id)
 FROM stats
 GROUP BY DAYOFMONTH(record_date)

希望這可以為將要找到此線程的人節省一些時間。

完整而簡單的解決方案,具有類似性能但更短、更靈活的替代方案,目前處於活動狀態:

SELECT COUNT(*) FROM stats
-- GROUP BY YEAR(record_date), MONTH(record_date), DAYOFMONTH(record_date)
GROUP BY DATE_FORMAT(record_date, '%Y-%m-%d')

您可以在 GROUP BY 中簡單地執行 Mysql DATE_FORMAT()函數。 在某些情況下,您可能需要添加一個額外的列以增加清晰度,例如記錄跨越幾年的情況,然后在不同的年份出現相同的月份。這里有很多選項,您可以對此進行自定義。 請在開始前閱讀此內容。 希望它對你很有幫助。 這是您理解的示例查詢

SELECT
    COUNT(id),
    DATE_FORMAT(record_date, '%Y-%m-%d') AS DAY,
    DATE_FORMAT(record_date, '%Y-%m') AS MONTH,
    DATE_FORMAT(record_date, '%Y') AS YEAR

FROM
    stats
WHERE
    YEAR = 2009
GROUP BY
    DATE_FORMAT(record_date, '%Y-%m-%d ');

如果您想獲得按最新月份排序的每年每月行數的月度統計數據,請嘗試以下操作:

SELECT count(id),
      YEAR(record_date),
      MONTH(record_date) 
FROM `table` 
GROUP BY YEAR(record_date),
        MONTH(record_date) 
ORDER BY YEAR(record_date) DESC,
        MONTH(record_date) DESC

以下查詢在 Oracle Database 12c 版本 12.1.0.1.0 中對我有用

SELECT COUNT(*)
FROM stats
GROUP BY 
extract(MONTH FROM TIMESTAMP),
extract(MONTH FROM TIMESTAMP),
extract(YEAR  FROM TIMESTAMP);

我更喜歡像這樣優化一年組選擇:

SELECT COUNT(*)
  FROM stats
 WHERE record_date >= :year 
   AND record_date <  :year + INTERVAL 1 YEAR;

通過這種方式,您只需將年份綁定一次,例如'2009' ,使用命名參數,而無需擔心添加'-01-01'或單獨傳入'2010'

另外,大概我們只是在計算行數,而id永遠不會是NULL ,我更喜歡COUNT(*)COUNT(id)

.... group by to_char(date, 'YYYY') --> 1989

.... group by to_char(date,'MM') -->05

.... group by to_char(date,'DD') --->23

.... group by to_char(date,'MON') ---> MAY

.... group by to_char(date,'YY') --->89

這是另一種方法。 這使用 [MySQL 的 LAST_DAY() 函數][1] 將每個時間戳映射到它的月份。 如果record_date上有索引, record_date能夠通過有效的范圍掃描按年份過濾。

  SELECT LAST_DAY(record_date) month_ending, COUNT(*) record_count
    FROM stats
   WHERE record_date >= '2000-01-01'
     AND record_date <  '2000-01-01' + INTERVAL 1 YEAR
   GROUP BY LAST_DAY(record_date) 

如果您希望按天顯示結果,請改用DATE(record_date)

如果您希望按日歷季度顯示結果,請使用YEAR(record_date), QUARTER(record_date)

這里有一篇記敘文。 https://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/ [1]: https : //dev.mysql.com/doc/refman/8.0/en/date-and-time-functions。 html#function_last-day

我想每天獲得類似的數據,經過一些試驗,這是我能找到的最快的場景

SELECT COUNT(id)
FROM stats
GROUP BY record_date DIV 1000000;

如果您想每月使用它,請添加額外的零 (00) 從“使代碼可讀”的角度來看,我不建議這樣做,它也可能會在不同版本中中斷。 但在我們的例子中,與我測試的其他一些更清晰的查詢相比,這花費的時間不到一半。

這是一個 MySQL 答案(因為 MySQL 在問題中被標記)並且在手冊https://dev.mysql.com/doc/refman/8.0/en/date-and-time-type-conversion.html 中有詳細記錄

試試看

GROUP BY YEAR(record_date), MONTH(record_date)

或者你可以像這樣使用 group by 子句,

//to get data by month and year do this ->
SELECT FORMAT(TIMESTAMP_COLUMN, 'MMMM yy') AS Month, COUNT(ID) FROM TABLE_NAME GROUP BY FORMAT(TIMESTAMP_COLUMN, 'MMMM yy')

如果你想按日期獲取記錄,然后在組中將格式更改為 'dd-mm-yy' 或 'dd-MMMM-yyy'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM