Sql 如何从给定季度计算上一季度和下一季度?
当我通过当前季度值时,我想计算上一个季度和下一个季度。例如,如果我通过了“Q3”或“Q4” 输出应为:Sql 如何从给定季度计算上一季度和下一季度?,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,当我通过当前季度值时,我想计算上一个季度和下一个季度。例如,如果我通过了“Q3”或“Q4” 输出应为: Current Quarter Previous Quarter Next Quarter ---------------------------------------------------------------------- Q3 Q2
Current Quarter Previous Quarter Next Quarter
----------------------------------------------------------------------
Q3 Q2 Q4
Q4 Q3 Q1
Oracle中是否有实现相同功能的功能
如何使用Select查询获得此输出
Oracle 11g R2架构设置:
查询2使用案例列举可能性:
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
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
查询3使用DECODE枚举可能性:
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
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
对于所有查询:
| CURRENT_Q | NEXT_Q | PREV_Q |
|-----------|--------|--------|
| Q1 | Q2 | Q4 |
| Q2 | Q3 | Q1 |
| Q3 | Q4 | Q2 |
| Q4 | Q1 | Q3 |
Oracle 11g R2架构设置:
查询2使用案例列举可能性:
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
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
查询3使用DECODE枚举可能性:
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
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
对于所有查询:
| CURRENT_Q | NEXT_Q | PREV_Q |
|-----------|--------|--------|
| Q1 | Q2 | Q4 |
| Q2 | Q3 | Q1 |
| Q3 | Q4 | Q2 |
| Q4 | Q1 | Q3 |
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
您可能会滥用日期操纵,将数字季度数拆分并从名义日期进行抵销:
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
但这似乎变得不必要的复杂…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
您可能会滥用日期操纵,将数字季度数拆分并从名义日期进行抵销:
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
但这似乎变得不必要的复杂…试试这个
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
试试这个
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