当我传递当前季度值时,我想计算上一个和下一个季度。所以例如如果我通过“ Q3”或“ Q4”,
输出应为:
Current Quarter Previous Quarter Next Quarter
----------------------------------------------------------------------
Q3 Q2 Q4
Q4 Q3 Q1
Oracle中是否有可用的功能来实现相同的功能?
如何使用“选择查询”到达此输出?
答案 0 :(得分:2)
Oracle 11g R2架构设置:
CREATE TABLE quarters ( value ) AS
SELECT 'Q' || LEVEL FROM DUAL CONNECT BY LEVEL <= 4;
查询1 ,使用SUBSTR
和MOD
计算下一个/上一个值:
SELECT value As current_q,
'Q' || ( MOD( SUBSTR( value, 2 ), 4 ) + 1 ) AS next_q,
'Q' || ( MOD( SUBSTR( value, 2 ) + 2, 4 ) + 1 ) AS prev_q
FROM quarters
查询2 使用CASE
来列举可能性:
SELECT value AS current_q,
CASE value
WHEN 'Q1' THEN 'Q2'
WHEN 'Q2' THEN 'Q3'
WHEN 'Q3' THEN 'Q4'
WHEN 'Q4' THEN 'Q1'
END As next_q,
CASE value
WHEN 'Q1' THEN 'Q4'
WHEN 'Q2' THEN 'Q1'
WHEN 'Q3' THEN 'Q2'
WHEN 'Q4' THEN 'Q3'
END As prev_q
FROM quarters
查询3 ,使用DECODE
列举可能性:
SELECT value AS current_q,
DECODE( value, 'Q1', 'Q2', 'Q2', 'Q3', 'Q3', 'Q4', 'Q4', 'Q1' ) AS next_q,
DECODE( value, 'Q1', 'Q4', 'Q2', 'Q1', 'Q3', 'Q2', 'Q4', 'Q3' ) AS prev_q
FROM quarters
Results (针对所有查询):
| CURRENT_Q | NEXT_Q | PREV_Q |
|-----------|--------|--------|
| Q1 | Q2 | Q4 |
| Q2 | Q3 | Q1 |
| Q3 | Q4 | Q2 |
| Q4 | Q1 | Q3 |
答案 1 :(得分:2)
Oracle不允许您将四分之一转换为完整日期。
最简单的事情可能是对组合进行硬编码,因为只有这么少:
with t (current_quarter) as (
select 'Q1' from dual
union all select 'Q2' from dual
union all select 'Q3' from dual
union all select 'Q4' from dual
)
select current_quarter,
case current_quarter
when 'Q1' then 'Q4'
when 'Q2' then 'Q1'
when 'Q3' then 'Q2'
when 'Q4' then 'Q3'
else 'invalid'
end as previous_quarter,
case current_quarter
when 'Q1' then 'Q2'
when 'Q2' then 'Q3'
when 'Q3' then 'Q4'
when 'Q4' then 'Q1'
else 'invalid'
end as next_quarter
from t;
CU PREVIOU NEXT_QU
-- ------- -------
Q1 Q4 Q2
Q2 Q1 Q3
Q3 Q2 Q4
Q4 Q3 Q1
尽管如此,您可以通过数学方法来实现,方法是将数字部分拆分并进行调整:
with t (current_quarter) as (
select 'Q1' from dual
union all select 'Q2' from dual
union all select 'Q3' from dual
union all select 'Q4' from dual
)
select current_quarter,
'Q' || (mod(to_number(substr(current_quarter, 2, 1)) + 2, 4) + 1) as previous_quarter,
'Q' || (mod(to_number(substr(current_quarter, 2, 1)), 4) + 1) as next_quarter
from t;
CU PREVIOUS_QUARTER NEXT_QUARTER
-- ----------------------------------------- -----------------------------------------
Q1 Q4 Q2
Q2 Q1 Q3
Q3 Q2 Q4
Q4 Q3 Q1
您可以(ab)使用日期操纵符,方法是分解数字四分之一数字并从标称日期偏移:
with t (current_quarter) as (
select 'Q1' from dual
union all select 'Q2' from dual
union all select 'Q3' from dual
union all select 'Q4' from dual
)
select current_quarter,
to_char(add_months(date '2000-01-01',
3 * (to_number(substr(current_quarter, 2, 1)) - 2)), '"Q"Q') as previous_quarter,
to_char(add_months(date '2000-01-01',
3 * to_number(substr(current_quarter, 2, 1))), '"Q"Q') as next_quarter
from t;
CU PR NE
-- -- --
Q1 Q4 Q2
Q2 Q1 Q3
Q3 Q2 Q4
Q4 Q3 Q1
但是这似乎变得不必要地复杂了...
答案 2 :(得分:0)
尝试一下
with tst as
(
Select level as lvl from dual CONNECT BY Level < 5
)
Select 'Q'||lvl as current_quarter,
'Q'||case when lvl = 1 then 4 else lvl - 1 end as previous_quarter,
'Q'||case when lvl = 4 then 1 else lvl + 1 end as next_quarter
from tst