У меня есть форма, которая подключена к базе данных, так что эта форма может иметь больше блоков, где каждый блок имеет дату с, дату до Например
Я пытаюсь сделать оператор SELECT
, который будет отображать количество дней между 01.08.2022
и 31.08.2022
.
Не могли бы вы помочь мне, ребята, с созданием этого выбора? Выбор должен иметь date_from
, date_until
и number of days
.
Правила генерации NULL для некоторых интервалов не ясны. Например, что, если интервал A находится в объединении интервалов B и C? Используя целые числа, A= 2..6, а B=1..4 и C=3..7.
@Серг, я не уверен, что ты имеешь в виду, не мог бы ты объяснить это, используя графику.
А = ************
И как вы решаете, что учитываются только 1-й и 4-й блоки; почему 1-й блок не 11 дней (1-11), 2-й блок 4 дня (12-15), 3-й блок 5 дней (16-20) и 4-й блок 11 дней (21-31)? Предполагая, что блоки перечислены и оценены в порядке начала...
Б+С=*****|**************
@serg, потому что первый блок начинается раньше, чем второй или третий, а также имеет больше дней в своем интервале
Почему вы выводите 2 блока (блок 1: 2022-08-01 до 2022-08-11 и блок 4: 2022-08-11 до 2022-08-31), а не 4 блока (блок 1: 2022-08-01 до 11 августа 2022 г., блок 2: 11 августа 2022 г. до 15 августа 2022 г., блок 3: 15 августа 2022 г. до 20 августа 2022 г. и блок 4 с 20 августа 2022 г. до 31 августа 2022 г. )? Какова логика выбора этих блоков?
WITH data(Block,Date_From,Date_until) AS (
SELECT 1, TO_DATE('25.07.2022','DD.MM.YYYY'), TO_DATE('11.08.2022','DD.MM.YYYY') FROM DUAL UNION ALL
SELECT 2, TO_DATE('05.08.2022','DD.MM.YYYY'), TO_DATE('15.08.2022','DD.MM.YYYY') FROM DUAL UNION ALL
SELECT 3, TO_DATE('10.08.2022','DD.MM.YYYY'), TO_DATE('20.08.2022','DD.MM.YYYY') FROM DUAL UNION ALL
SELECT 4, TO_DATE('11.08.2022','DD.MM.YYYY'), TO_DATE('05.09.2022','DD.MM.YYYY') FROM DUAL -- UNION ALL
),
clipped(Block,Date_From,Date_until) AS (
SELECT Block, GREATEST(Date_From, TO_DATE('01.08.2022','DD.MM.YYYY')), LEAST(Date_until, TO_DATE('31.08.2022','DD.MM.YYYY')) FROM DATA
)
SELECT c.*,
CASE WHEN NOT(
EXISTS(SELECT 1 FROM clipped d WHERE d.Date_From < c.Date_until AND d.Date_until > c.Date_From AND d.block < c.block)
AND
EXISTS(SELECT 1 FROM clipped d WHERE d.Date_From < c.Date_until AND d.Date_until > c.Date_From AND d.block > c.block) )
THEN c.Date_until - c.Date_from ELSE NULL
END AS days
FROM clipped c
ORDER BY c.block
;
1 01/08/22 11/08/22 10
2 05/08/22 15/08/22
3 10/08/22 20/08/22
4 11/08/22 31/08/22 20
Если последняя строка выборочных данных — SELECT 4, TO_DATE('14.08.2022','DD.MM.YYYY'), TO_DATE('05.09.2022','DD.MM.YYYY') FROM DUAL
, то 12.08 и 13.08 не учитываются. Это правильно?
Не уверен, что понимаю, но это похоже на проблему пробелов и островов?