2010-07-21 39 views
35

Tôi muốn có ngày đầu tiên của mỗi tháng tương ứng của năm hiện tại. Ví dụ: nếu người dùng chọn '2010-06-15', truy vấn yêu cầu chạy từ '2010-06-01' thay vì '2010-06-15'.Làm thế nào để có được ngày đầu tiên của mỗi tháng tương ứng trong mysql?

Vui lòng giúp tôi cách tính ngày đầu tiên từ ngày đã chọn. Hiện nay, tôi đang cố gắng để có được mong muốn sử dụng mysql sau chọn truy vấn:

Select 
    DAYOFMONTH(hrm_attendanceregister.Date) >= 
    DAYOFMONTH(
    DATE_SUB('2010-07-17', INTERVAL - DAYOFMONTH('2010-07-17') + 1 DAY 
) 
FROM 
    hrm_attendanceregister; 

Cảm ơn

Trả lời

1

sử dụng date_format phương pháp và kiểm tra chỉ tháng & năm

select * from table_name where date_format(date_column, "%Y-%m")="2010-06" 
+0

[Không sử dụng định dạng ngày] (http://stackoverflow.com/questions/3298288/how-to-get-first-day-of-every-corresponding-month-in-mysql/28966866#comment- 46185420), nó chậm. – Pacerier

62

này những gì bạn đang tìm kiếm là:

select CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE); 
+3

Đây là chi phí không cần thiết. Bạn đang chuyển đổi ngày thành chuỗi rồi quay lại ngày nữa. Giải pháp của tôi tốt hơn nhiều. – Pacerier

+1

Đây là cách tốt hơn so với câu trả lời của tôi. – Thomas

-1
select big.* from 
(select @date := '2010-06-15')var 
straight_join 
(select * from your_table where date_column >= concat(year(@date),'-',month(@date),'-01'))big; 

Điều này sẽ không tạo bản quét toàn bộ bảng.

7

Bạn có thể sử dụng EXTRACT để có được những phần ngày bạn muốn:

EXTRACT(YEAR_MONTH FROM DATE('2011-09-28')) 
-- 201109 

này hoạt động tốt cho nhóm.

26

Bạn có thể sử dụng LAST_DAY chức năng được cung cấp bởi MySQL để lấy ngày cuối cùng của bất kỳ tháng nào, đó là dễ dàng:

SELECT LAST_DAY('2010-06-15'); 

Sẽ trả lại:

2010-06-30 

Thật không may, MySQL không cung cấp bất kỳ FIRST_DAY để truy xuất ngày đầu tiên của tháng (không chắc chắn lý do). Nhưng cho ngày cuối cùng, bạn có thể thêm một ngày và trừ một tháng để có được ngày đầu tiên. Vì vậy bạn có thể xác định một chức năng tùy chỉnh:

DELIMITER ;; 
CREATE FUNCTION FIRST_DAY(day DATE) 
RETURNS DATE DETERMINISTIC 
BEGIN 
    RETURN ADDDATE(LAST_DAY(SUBDATE(day, INTERVAL 1 MONTH)), 1); 
END;; 
DELIMITER ; 

Bằng cách đó:

SELECT FIRST_DAY('2010-06-15'); 

Sẽ trả lại:

2010-06-01 
+0

Giải pháp 'FIRST_DAY' của bạn là gián tiếp ngữ nghĩa bởi vì bạn đang thêm 1 ngày vào ngày cuối cùng của tháng trước thay vì chỉ đơn giản là trừ số ngày mà ngày hiện tại có.Tham khảo giải pháp của tôi. – Pacerier

13

Đây là cũ nhưng điều này có thể hữu ích cho trình thu thập web con người mới XD

Cho ngày đầu tiên của tháng hiện tại bạn có thể sử dụng:

SELECT LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY; 
+0

Không hiệu quả. Sử dụng phép trừ một ngày và thêm một ngày khi thực sự chỉ cần một phép trừ ngày. Tham khảo giải pháp của tôi. – Pacerier

0
date_add(subdate(curdate(), interval day(?) day), interval 1 day) 

thay đổi? cho ngày tương ứng

+0

Không hiệu quả bởi vì bạn sử dụng một ngày bổ sung và một phép trừ ngày khi chỉ cần một phép trừ ngày. Ngoài ra, [thay vì 'date_add', sử dụng 2-arity' AddDate'] (http://stackoverflow.com/a/28966866/632951) có hiệu suất cao hơn. – Pacerier

25

Có thực sự là một giải pháp đơn giản kể từ ngày đầu tiên của tháng đơn giản today - (day_of_month_in_today - 1) là:

select now() - interval (day(now())-1) day 

Contrast rằng với các other methods đó là cực kỳ bùng binh và gián tiếp.


Ngoài ra, vì chúng tôi không quan tâm đến các thành phần thời gian, curdate() là một tốt hơn (và nhanh hơn) chức năng hơn now(). Chúng ta cũng có thể tận dụng sự quá tải 2-arity của subdate() vì nó có hiệu suất cao hơn sử dụng interval. Vì vậy, một giải pháp tốt hơn là:

select subdate(curdate(), (day(curdate())-1)) 
+1

thực hiện tốt các khoảng thời gian – Zordon

+1

câu trả lời tốt, tôi nghĩ rằng đây là giải pháp thanh lịch và hiệu quả nhất – fthiella

+3

Vì bạn dường như chỉ trích giải pháp của mọi người khác, bạn có thể có ít nhất trả lời câu hỏi đúng cho mình. Người đã hỏi về việc sử dụng "ngày đã chọn" không phải là ngày hiện tại. 'CHỌN SUBDATE (DATE ('2010-06-15'), (DAY (DATE ('2010-06-15')) - 1))' – Ray

1

Tôi ngạc nhiên không ai đã đề nghị một cái gì đó tương tự như này (tôi không biết làm thế nào performant nó là):

CONCAT_WS('-', YEAR(CURDATE()), MONTH(CURDATE()), '1') 

hoạt động ngày bổ sung có thể được thực hiện để xóa định dạng, nếu cần

2

Bạn có thể sử dụng hàm DATE_FORMAT() để có được ngày đầu tiên của bất kỳ trường ngày nào.

SELECT DATE_FORMAT(CURDATE(),'%Y-%m-01') as FIRST_DAY_CURRENT_MONTH 
FROM dual; 

Thay đổi Curdate() với bất kỳ lĩnh vực ngày khác như:

SELECT DATE_FORMAT(purchase_date,'%Y-%m-01') AS FIRST_DAY_SALES_MONTH 
FROM Company.Sales; 

Sau đó, sử dụng câu hỏi của riêng bạn:

SELECT * 
FROM 
    hrm_attendanceregister 
WHERE 
hrm_attendanceregister.Date) >= 
DATE_FORMAT(CURDATE(),'%Y-%m-01') 

Bạn có thể thay đổi CURDATE() với bất cứ ngày khác .

0

Điều này phù hợp với tôi.

date(SUBDATE("Added Time", INTERVAL (day("Added Time") -1) day)) 

** thay thế "Thời gian gia tăng" với tên cột

Trường hợp sử dụng:

  1. Nếu bạn muốn đặt lại tất cả các lĩnh vực ngày trừ ThángNăm.

  2. Nếu bạn muốn giữ nguyên định dạng cột là "ngày". (Không phải là "văn bản" hoặc "số")

0

chậm (17s): CHỌN Benchmark (100000000, current_date - INTERVAL (ngày (current_date) -1) NGÀY); SELECT BENCHMARK (100000000, truyền (DATE_FORMAT (current_date, '% Y-% m-01') làm ngày));

Nếu bạn không cần loại ngày này nhanh hơn: Nhanh (6s): CHỌN BENCHMARK (100000000, DATE_FORMAT (CURDATE(), '% Y-% m-01')); SELECT BENCHMARK (100000000, DATE_FORMAT (current_date, '% Y-% m-01'));

Các vấn đề liên quan