2009-07-16 38 views
18

Tôi muốn tính tổng số tiền đặt hàng trong tháng trước.Truy vấn MySQL để tính tháng trước

Tôi nhận được truy vấn để nhận dữ liệu cho tháng hiện tại từ ngày hiện tại.

SELECT SUM(goods_total) AS Total_Amount FROM orders 
WHERE order_placed_date >= date_sub(current_date, INTERVAL 1 MONTH); 

Bây giờ làm cách nào tôi có thể nhận Dữ liệu tháng trước, ngoại trừ tháng này.

Ví dụ: Tháng này (tháng 7) tôi kiếm được 15.000 đô la và tháng trước (tháng 6) tôi kiếm được 14.000 đô la.

Tôi nhận được $ 15.000 bằng cách chạy truy vấn ở trên.

Nhưng tôi không biết cách tính tháng trước.

+0

"Ở ĐÂU VÀ" - đưa ra AND. –

+0

Cảm ơn bạn đã chỉ ra nó, tôi đã có nó trong đó vô tình. –

Trả lời

47

Ở đây bạn đi, sử dụng này để có được những ngày giữa ngày 1 tháng trước và cuối cùng của tháng cuối cùng trong MySQL:

... order_placed_date BETWEEN DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%Y-%m-01 00:00:00') AND DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 1 MONTH), '%Y-%m-%d 23:59:59')

+0

Bạn được chào đón. Tôi đã có cùng một vấn đề một vài tháng trở lại và đã đưa ra điều đó. –

+1

Cảm ơn bạn đã hoạt động hoàn hảo, kết quả phù hợp với dữ liệu của tôi. –

+0

Tôi đang sử dụng current_date thay vì NGAY BÂY GIỜ() –

0

Nếu bạn là lười biếng nó kinda thuận tiện để sử dụng

...date_format(order_placed_date, '%Y-%m') = date_format(now() - INTERVAL 1 MONTH, '%Y-%m')

Tôi nghĩ nó cũng làm tăng khả năng đọc.

+0

Vấn đề với truy vấn của bạn là nó sẽ thực hiện quét toàn bộ bảng và sẽ có hiệu suất kinh khủng trên các tập dữ liệu lớn vì nó sẽ không sử dụng chỉ mục. Truy vấn với GIỮA mà tôi đã đăng sử dụng một phạm vi, vì vậy nó sẽ có thể sử dụng một chỉ mục. Khả năng đọc ...Tôi nghĩ cả hai đều có thể đọc được :) –

+0

Oh và FYI, MySQL không hỗ trợ các chỉ mục dựa trên chức năng. PostgreSQL được cho là có. –

+0

Xin lỗi, tôi thấy điều đó ngay bây giờ. Tôi chỉ sử dụng làm điều đó từ các bảng với tối đa vài trăm bản ghi. Cảm ơn. –

0

Dưới đây là một cách tôi tìm thấy:

SELECT SUM(goods_total) AS Total_Amount FROM orders 
WHERE SUBSTRING(o.order_placed_date FROM 1 FOR 7) = SUBSTRING(CURRENT_DATE - INTERVAL 1 MONTH FROM 1 FOR 7) 

này hoạt động là tốt.

+0

Cùng một vấn đề như trên, tôi sẽ nghĩ. Chạy tất cả các lệnh SELECT thông qua GIẢI THÍCH (chỉ cần thêm EXPLAIN vào mỗi SELECT) và xem loại thông tin nào GIẢI THÍCH cung cấp cho bạn về hiệu quả của mỗi truy vấn. –

+0

Tức là bạn đã tạo một chỉ mục trên order_placed_date. Bạn đã làm đúng? ĐÚNG? –

+0

Theo Chỉ mục, các cài đặt order_placed_date là: Non_Unique = 1, Seq_in_Index = 1, IndexType = BTREE –

7

Tôi thấy rằng truy vấn của Artem không trả lại bất cứ điều gì từ ngày cuối cùng của tháng trước đó (có lẽ là BETWEEN sẽ tính từ thời điểm 00:00:00 của ngày trước).

Điều này có vẻ phù hợp với tôi trong tháng trước.

order_placed_date BETWEEN DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%Y-%m-01') 
AND DATE_FORMAT(NOW() ,'%Y-%m-01') 
+0

Cảm ơn bạn, hãy thử nó –

+0

Tôi đã cập nhật truy vấn của mình hoạt động chính xác, hơi khác so với của bạn. –

+0

Có vẻ tốt. – Shane

0

đây một giải pháp - mà không stringoperation

SELECT SUM(goods_total) AS Total_Amount FROM orders 
WHERE DATE(order_placed_date) 
BETWEEN DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY) 
AND LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)); 
3

giải pháp đơn giản nhất:

SELECT SUM(goods_total) AS Total_Amount FROM orders 
WHERE YEAR(order_placed_date) = YEAR(CURDATE() - INTERVAL 1 MONTH) 
AND MONTH(order_placed_date) = MONTH(CURDATE() - INTERVAL 1 MONTH)