Sql 如何从给定季度计算上一季度和下一季度?

Sql 如何从给定季度计算上一季度和下一季度?,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,当我通过当前季度值时,我想计算上一个季度和下一个季度。例如,如果我通过了“Q3”或“Q4” 输出应为: Current Quarter Previous Quarter Next Quarter ---------------------------------------------------------------------- Q3 Q2

当我通过当前季度值时,我想计算上一个季度和下一个季度。例如,如果我通过了“Q3”或“Q4”

输出应为:

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