С SQLite вы можете использовать что-то вроде: -
WITH
cte_month_start AS (SELECT 16) /* THE START DAY FOR THE MONTH */,
/* REFORMAT THE DATE TO YYYY-MM-DD format*/
cte_reformatted_date(rdate) AS (
SELECT(substr(mydate,7,4)||'-'||substr(mydate,4,2)||'-'||substr(mydate,1,2))
FROM mytable
),
/* SUBTRACT 1 FROM THE MONTH IF THE DAY OF THE MONTH IS LESS THAN THE START DAY */
cte_adjusted_date(adate) AS (
SELECT
CASE
WHEN CAST(strftime('%d',rdate) AS INTEGER) < (SELECT * FROM cte_month_start)
THEN date(rdate,'-1 months')
ELSE rdate
END
FROM cte_reformatted_date
)
SELECT substr(adate,9,2)||'/'||substr(adate,6,2)||'/'||substr(adate,1,4) AS mydate FROM cte_adjusted_date;
Это использует 3 C ommon T способны E xpressions (временныетаблицы, доступные в запросе)
Первый - это начальный день месяца, который обеспечивает гибкость
- , т. е. начальный день месяца можетлегко передаваться и, таким образом, изменяться.
Вторая переформатирует дату в такую, которой SQLites может легко манипулировать Функции даты и времени
Третий использует прежние CTE для вывода либо неизмененной даты (если день месяца не меньше, чем начальный день месяца), либо даты, скорректированной путем вычитания 1 месяца издата, если день месяца меньше даты начала.
Вам на самом деле не нужны CTE, они могут быть встроены, но их использование может облегчить понимание кода.
С SQLite, если датытод в распознаваемом формате (по ссылке), тогда манипулирование датами будет проще.
Пример / Демо
/* PREPARE TEST ENVIROMENT BY CREATING AND POPULATING TABLES */
DROP TABLE IF EXISTS mytable;
CREATE TABLE If NOT EXISTS mytable(mydate TEXT);
INSERT INTO mytable VALUES
('16/09/2019'),('17/09/2019'),('18/09/2019'), /* DATES UNCHANGED */
('01/10/2019'),('02/10/2019'),('11/10/2019'), /* DATES THAT WILL BE ADJUSTED (month reduced)*/
('16/08/2019'),('11/09/2019') /* Other dates */
;
/* THE ACTUAL TEST */
WITH
cte_month_start AS (SELECT 16) /* THE START DAY FOR THE MONTH */,
/* REFORMAT THE DATE TO YYYY-MM-DD format*/
cte_reformatted_date(rdate) AS (
SELECT(substr(mydate,7,4)||'-'||substr(mydate,4,2)||'-'||substr(mydate,1,2))
FROM mytable
),
/* SUBTRACT 1 FROM THE MONTH IF THE DAY OF THE MONTH IS LESS THAN THE START DAY */
cte_adjusted_date(adate) AS (
SELECT
CASE
WHEN CAST(strftime('%d',rdate) AS INTEGER) < (SELECT * FROM cte_month_start)
THEN date(rdate,'-1 months')
ELSE rdate
END
FROM cte_reformatted_date
)
/* RESULTS OF THE TEST */
SELECT substr(adate,9,2)||'/'||substr(adate,6,2)||'/'||substr(adate,1,4) AS mydate FROM cte_adjusted_date;
DROP TABLE IF EXISTS mytable; /* CLEAN UP TEST ENVIRONMENT */
Результат: -
Как видно, выделенные строки были соответствующим образом скорректированы.