2010-07-21 2 views
35

Я хочу получить первый день каждого соответствующего месяца текущего года. Например, если пользователь выбирает «2010-06-15», запрос требует выполнения от «2010-06-01» вместо «2010-06-15».Как получить первый день каждого месяца в mysql?

Пожалуйста, помогите мне рассчитать первый день с выбранной даты. В настоящее время я пытаюсь получить желаемое с помощью следующего MySQL выберите запрос:

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

Благодарность

ответ

1

использовать date_format метод и проверить как раз месяц & года

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

[Не использовать формат даты] (http://stackoverflow.com/questions/3298288/how-to-get-first-day-of-every-corresponding-month-in-mysql/28966866#comment- 46185420), это медленно. – Pacerier

62

Это то, что вы ищете:

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

Это лишние накладные расходы. Вы конвертируете дату в строку, а затем обратно. Мое решение намного лучше. – Pacerier

+1

Это лучше, чем мой ответ. – 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; 

Это не приведет к полному сканированию таблицы.

7

Вы можете использовать EXTRACT, чтобы получить дату детали, которые вы хотите:

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

Это хорошо работает для группировки.

26

Вы можете использовать функцию LAST_DAY предоставляемые MySQL, чтобы получить последний день любого месяца, это легко:

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

Вернется:

2010-06-30 

К сожалению, MySQL не предоставляет FIRST_DAY функция для получения первого дня месяца (не знаю, почему). Но, учитывая последний день, вы можете добавить день и вычесть месяц, чтобы получить первый день. Таким образом, можно определить пользовательскую функцию:

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

этак:

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

Вернется:

2010-06-01 
+0

Ваше решение 'FIRST_DAY' является семантически косвенным, потому что вы добавляете 1 день до последнего дня предыдущего месяца, а не просто вычитаете количество дней, которое имеет текущая дата.Обратитесь к моему решению. – Pacerier

13

Это старый, но это может быть полезным для нового человека веб-гусеничном XD

В первый день текущего месяца вы можете использовать:

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

Неэффективен. Использует одно вычитание по дате и одно добавление даты, когда требуется только одно вычитание даты. Обратитесь к моему решению. – Pacerier

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

изменить? для соответствующей даты

+0

Неэффективен, потому что вы используете одно добавление даты и вычитание даты, когда требуется только одно вычитание даты. Кроме того, [вместо 'date_add', используйте 2-arity' AddDate'] (http://stackoverflow.com/a/28966866/632951), который более эффективен. – Pacerier

25

Существует на самом деле простое решение, так как первый день месяца просто today - (day_of_month_in_today - 1):

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

Контраст, что с other methods на которые чрезвычайно окольный и косвенные.


Кроме того, поскольку мы не заинтересованы во временном компоненте, curdate() функция лучше (и быстрее), чем now(). Мы также можем воспользоваться перегрузкой 2-arity subdate(), поскольку она более эффективна, чем при использовании interval. Таким образом, лучшим решением является:

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

хорошая реализация интервала – Zordon

+1

хороший ответ, я думаю, что это самое элегантное и эффективное решение. – fthiella

+3

Поскольку вы, казалось, критиковали решение остальных, вы могли бы, по крайней мере, сами ответить на вопрос. Человек спросил об использовании «выбранной даты», а не текущей даты. 'SELECT SUBDATE (DATE ('2010-06-15'), (DATE ('2010-06-15')) - 1))' – Ray

1

Я удивлен, что никто не предложил что-то похожее на это (я не знаю, как производительный это):

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

Дополнительные операции дата может быть выполнена в удалять форматирование, если необходимо

2

Вы можете использовать функцию DATE_FORMAT(), чтобы получить первый день любого поля даты.

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

Изменение CurDate() с любым другим полем Даты, как:

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

Затем, используя свой собственный вопрос:

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

Вы можете изменить CurDate() с любой другой заданной датой ,

0

Это отлично работает для меня.

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

** заменяющие "добавленное время" с именем столбца

Прецеденты:

  1. Если вы хотите сбросить все поля даты кроме Месяц и года.

  2. Если вы хотите сохранить формат столбца как «дата». (Не как "текст" или "номер")

0

Медленный (17s): ВЫБОР ЭТАЛОН (100000000, текущая_дат - ИНТЕРВАЛ (день (текущая_дат) -1) ДЕНЬ); SELECT BENCHMARK (100000000, cast (DATE_FORMAT (current_date, '% Y-% m-01') в качестве даты));

Если вам не нужен тип даты это быстрее: Fast (6с): ВЫБРАТЬ ЭТАЛОН (100000000, DATE_FORMAT (CURDATE(), '% Y-% м-01')); SELECT BENCHMARK (100000000, DATE_FORMAT (current_date, '% Y-% m-01'));

Смежные вопросы