MYSQL Как выполнить пользовательскую разницу в месяце между двумя датами в MYSQL? - PullRequest
0 голосов
/ 10 декабря 2018

Мое требование состоит в том, чтобы вычислить общее количество месяцев и затем разбитых месяцев отдельно между 2 датами (т.е. первая дата из таблицы, а вторая дата - текущая дата).Если общее количество неработающих месяцев> 15, то учитывайте его как опыт за один месяц, а если его значения меньше 15, не считайте это как опыт за 1 месяц.

Предположим, у меня на столе дата 25/11/2018и текущая дата - 01.06.2009;полный месяц между ними - декабрь, поэтому 1 месяц опыта;и разбитыми месяцами являются ноябрь и январь, так что теперь я должен посчитать даты, которые составляют 6 дней в ноябре и 6 дней в январе, поэтому 12 дней и <= (lte) 15, поэтому общий опыт будет округлен до 1 месяца опыта </p>

Я ответил на несколько вопросов, связанных с вычислением разницы дат в MYSQL из stackoverflow, но не смог найти никаких возможных вариантов.Встроенные функции в MYSQL TIMESTAMPDIFF, TIMEDIFF, PERIOD_DIFF, DATE_DIFF не дают моего требуемого результата, так как их логарифмы отличаются от моих требований к вычислениям.

Любая подсказка о том, как выполнить это вычисление в MYSQL и получить его результат как частьоператора SQL будет полезен для меня.Как только это значение будет получено, в том же SQL это значение будет проверено на соответствие заданному диапазону значений.

Включая пример структуры таблицы и значение:

table_name = "user"

id | name | join_date 
---------------------
1| Sam | 25-11-2017
2| Moe | 03-04-2017
3| Tim | 04-07-2018
4| Sal | 30-01-2017
5| Joe | 13-08-2018

Я хотел найтииз таблицы пользователей выше, чей опыт рассчитывается в месяцах на основе вышеупомянутой логики.Если эти месяцы находятся в пределах одного из следующих диапазонов, то эти пользователи выбираются для дальнейшей обработки.

table_name: "allowed_exp_range"
starting_exp_months | end_exp_months
-------------------------------------
0 | 6
9 | 24

Например, опыт Сэма до даты (10-12-2018), согласно моим расчетам, равен 12 + 1.месяц = ​​13 месяцев.Поскольку 13 находится между 9 и 24, запись Сэма является одним из ожидаемых результатов.

1 Ответ

0 голосов
/ 10 декабря 2018

Я думаю, что этот запрос будет делать то, что вы хотите.Он использует

  (YEAR(CURDATE())*12+MONTH(CURDATE()))
- (YEAR(STR_TO_DATE(join_date, '%d-%m-%Y'))*12+MONTH(STR_TO_DATE(join_date, '%d-%m-%Y'))) -
- 1

, чтобы получить количество полных месяцев опыта для пользователя,

  DAY(LAST_DAY(STR_TO_DATE(join_date, '%d-%m-%Y')))
- DAY(STR_TO_DATE(join_date, '%d-%m-%Y'))
+ 1

, чтобы получить количество дней в первом месяце, и

DAY(CURDATE())

чтобы получить количество дней в текущем месяце.Двухдневное число суммируется, и если общее число> 15, 1 добавляется к числу целых месяцев, например,

SELECT id
     , name
     , (YEAR(CURDATE())*12+MONTH(CURDATE())) - (YEAR(STR_TO_DATE(join_date, '%d-%m-%Y'))*12+MONTH(STR_TO_DATE(join_date, '%d-%m-%Y'))) - 1 -- whole months
       + CASE WHEN DAY(LAST_DAY(STR_TO_DATE(join_date, '%d-%m-%Y'))) - DAY(STR_TO_DATE(join_date, '%d-%m-%Y')) + 1 + DAY(CURDATE()) > 15 THEN 1 ELSE 0 END -- broken month
       AS months
FROM user

Мы можем использовать это выражение как JOIN условие между user и allowed_exp_range, чтобы найти всех пользователей, имеющих опыт работы в заданном диапазоне:

SELECT u.id
     , u.name
     , a.starting_exp_months
     , a.end_exp_months
FROM user u
JOIN allowed_exp_range a
ON (YEAR(CURDATE())*12+MONTH(CURDATE())) - (YEAR(STR_TO_DATE(u.join_date, '%d-%m-%Y'))*12+MONTH(STR_TO_DATE(u.join_date, '%d-%m-%Y'))) - 1
       + CASE WHEN DAY(LAST_DAY(STR_TO_DATE(u.join_date, '%d-%m-%Y'))) - DAY(STR_TO_DATE(u.join_date, '%d-%m-%Y')) + 1 + DAY(CURDATE()) > 15 THEN 1 ELSE 0 END
       BETWEEN a.starting_exp_months AND a.end_exp_months

Вывод (для ваших примеров данных включает всех пользователей, поскольку они все вписываются в один из диапазонов опыта):

id  name    starting_exp_months     end_exp_months
1   Sam     9                       24
2   Moe     9                       24
3   Tim     0                       6
4   Sal     9                       24
5   Joe     0                       6

Я создал небольшую демоверсию для dbfiddle , которая демонстрирует этапы получения результата.

...