/ / PL / SQL - використання умовного оператора в пункті "where" для виконання між двома датами - sql, oracle, oracle11g,

PL / SQL - Використання умовного виразу в пункті "where" для запуску між двома датами - sql, oracle, oracle11g, where

Прошу вибачити моє дуже обмежене знання PL / SQL.

Я намагаюся використовувати умовний оператор упункт де. У мене є скрипт, який буде працювати там, де run_date знаходиться між сьогодні і вчора, однак, якщо день тижня є понеділок, він повинен працювати там, де run_date знаходиться між сьогоднішньою-3 і сьогодні-2.

Я вважаю, що питання пов'язане з умовамиЯ намагаюся застосувати оператор CASE (наприклад, нижче) - але це повертає лише одне значення, тоді як мені потрібно повернути спосіб, за допомогою якого скрипт повинен працювати між двома датами.

Код - (де я намагався реалізувати випадок справи)

select record_type a, count(record_type) b
from orf_po_data
where
(CASE
WHEN ((to_char(sysdate, "D")) = "1") THEN (between trunc(sysdate-3) and trunc(sysdate-2))
WHEN ((to_char(sysdate, "D")) > "1" and (to_char(sysdate, "D")) <= "5") THEN (between trunc(sysdate-1) and trunc(sysdate)
ELSE null
END) run_date

group by record_type
order by record_type

Будь-яка допомога з цим буде оцінена, якщо комусь потрібно більше інформації, не соромтеся запитати, і я вам скажу, що я знаю (хоча у мене дуже обмежений досвід роботи з таким середовищем)

Дякую,

Відповіді:

0 для відповіді № 1
 Where datecolumn >= case ...... end -- start point
And datecolumn < case ..... end -- end point

Розділіть вираз справи на 2 частини і порівняйте дані з цими розрахунками.


0 для відповіді № 2

Ви можете переписати WHERE стан з деякими булевими логіками; якщо я добре розумію, вам може знадобитися:

WHERE ( to_char(sysdate, "D") = "1" AND
run_date between sysdate-1 and sysdate
)
OR
( to_char(sysdate, "D") != "1" AND
run_date between sysdate-3 and sysdate -2
)

Те, що ви написали, використовує CASE, що не є поганою ідеєю, але використовує її яктвердження, не даючи значення, що повертається, замість того, щоб використовувати його як вираз (для обчислення значення), порівнюючи його значення з деякими іншими даними. Однак я вважаю за краще, щоб мої умови були якомога більш ясними, тому я зазвичай намагаюся писати їх за допомогою логічної логіки; це, звичайно, моя власна точка зору, не враховуючи продуктивність.

Врахуйте, що я просто змінив вашумови, якщо вони є правильними; Наприклад, ви повинні розглянути truncatig значення, якщо вам потрібно перевірити ваші умови на основі днів і навіть не годин, хвилин, ... \ t


0 для відповіді № 3
CASE WHEN case_a THEN filter_a
WHEN case_b THEN filter_b
ELSE exclude_the_row END

Можна переписати як:

WHERE ( case_a AND filter_a )
OR    ( NOT case_a AND case_b AND filter_b )

Оскільки ваші умови для case_a і case_b (to_char(sysdate, "D") = "1" і to_char(sysdate, "D") > "1") є взаємовиключними, тоді ви можете ігнорувати NOT case_a частина і логіка:

WHERE (    TO_CHAR(SYSDATE, "D") = "1"
AND run_date BETWEEN TRUNC(SYSDATE-3) AND TRUNC(SYSDATE-2) )
OR    (    TO_CHAR(SYSDATE, "D") > "1" AND TO_CHAR(SYSDATE, "D") <= "5"
AND run_date BETWEEN TRUNC(SYSDATE-1) AND TRUNC(SYSDATE) )

Ви повинні знати, що NLS_TERRITORY Параметр session впливає на те, чи є понеділокперший день тижня (на деяких територіях це не так), і якщо ви будете впливати на це, ви можете отримати числове значення для дня тижня (незалежно від території), використовуючи:

1 + TRUNC( SYSDATE ) - TRUNC( SYSDATE, "IW" )

0 для відповіді № 4

Щоб досягти найкращої продуктивності, потрібно мати однуумова у вашому стовпці дати (особливо, якщо індекс, який оптимізатор може використовувати), порівнюючи з значеннями, які можуть бути оцінені статично під час виконання.

where datecolumn
between trunc(sysdate) - case when to_char(sysdate, "D") = "1" then 3 else 1 end
and trunc(sysdate) - case when to_char(sysdate, "D") = "1" then 2 else 0 end

Зверніть увагу також на коментарі MT0 nls_territory при визначенні дня тижня.