oracle 将表示年级数据的表中的单行转换为12行,以表示月级数据

o75abkj4  于 2023-03-29  发布在  Oracle
关注(0)|答案(3)|浏览(137)

我有一个表,它提供了货币汇率的细节,在一年的水平。这是1为每年的记录。我需要将每行转换成12行,以代表在月的数据水平。这就像复制到12行(12个月)的单行和唯一的区别将是在日期列,需要显示12个月。
示例

输入表

身份证日期兑换率
120221.8岁
2021二、九

必填输出

身份证日期兑换率
1二○二二年一月1.8岁
12022年2月1.8岁
12022年3月1.8岁
我的天我的天我的天
12022年12月1.8岁
2021年1月二、九
二○二一年二月二、九
我的天我的天我的天
2021年12月二、九

等等。
我想创建一个12行的静态表,并将其与我的输入表交叉连接,但我没有批准创建一个新表。

i2byvkas

i2byvkas1#

不需要创建表;您可以使用子查询或子查询因子分解(WITH)子句生成等效项:

WITH months (month) AS (
  SELECT 'Jan' FROM DUAL UNION ALL
  SELECT 'Feb' FROM DUAL UNION ALL
  SELECT 'Mar' FROM DUAL UNION ALL
  SELECT 'Apr' FROM DUAL UNION ALL
  SELECT 'May' FROM DUAL UNION ALL
  SELECT 'Jun' FROM DUAL UNION ALL
  SELECT 'Jul' FROM DUAL UNION ALL
  SELECT 'Aug' FROM DUAL UNION ALL
  SELECT 'Sep' FROM DUAL UNION ALL
  SELECT 'Oct' FROM DUAL UNION ALL
  SELECT 'Nov' FROM DUAL UNION ALL
  SELECT 'Dec' FROM DUAL
)
SELECT id,
       TO_DATE(month || '-' || "DATE", 'Mon-YYYY', 'NLS_DATE_LANGUAGE=English') AS "DATE",
       exchange_rate
FROM   table_name t
       CROSS JOIN months m

或者,您可以使用集合:

SELECT t.id,
       ADD_MONTHS(TO_DATE(t."DATE" || '-01', 'YYYY-MM'), m.COLUMN_VALUE) AS "DATE",
       t.exchange_rate
FROM   table_name t
       CROSS JOIN TABLE(SYS.ODCINUMBERLIST(0,1,2,3,4,5,6,7,8,9,10,11)) m

或行生成器:

WITH months (id, month, "DATE", exchange_rate) AS (
  SELECT id, 1, "DATE", exchange_rate
  FROM   table_name
UNION ALL
  SELECT id, month + 1, "DATE", exchange_rate
  FROM   months
  WHERE  month < 12
)
SELECT id,
       TO_DATE("DATE" || '-' || month, 'YYYY-MM') AS "DATE",
       exchange_rate
FROM   months;

其中,对于示例数据:

CREATE TABLE table_name (id, "DATE", exchange_rate) AS
  SELECT 1, 2022, 1.8 FROM DUAL UNION ALL
  SELECT 2, 2021, 2.9 FROM DUAL;

所有输出:
| ID|日期|汇率|
| --------------|--------------|--------------|
| 1|2022年01月01日00时00分|1.8岁|
| 1|2022年2月1日00时00分|1.8岁|
| ……|……|……|
| 1|2022年12月1日上午00时00分|1.8岁|
| 二|2022年01月01日00时00分|二、九|
| 二|2022年2月1日00时00分|二、九|
| ……|……|……|
| 二|2021年12月1日上午00时00分|二、九|

  • 注意:DATE是一个保留字,你不应该使用它作为标识符;如果你这样做,那么你需要使用一个带引号的标识符。

fiddle

oxf4rvwz

oxf4rvwz2#

它是关于某种行生成器的;这是一个选择
我正在设置日期格式(这样你就知道what is what)。结果以该格式显示;你可以切换到Mon-yyyy或任何其他格式,如果你想-无论是在会话级别,或通过应用to_char函数,...无论什么。

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

样本数据:

SQL> with input_table (id, datum, exchangerate) as
  2    (select 1, 2022, 1.8 from dual union all
  3     select 2, 2021, 2.9 from dual
  4    )

查询从此处开始:

5  select
  6    id,
  7    add_months(trunc(to_date(datum, 'yyyy'), 'yyyy'), column_value - 1) datum,
  8    exchangerate
  9  from input_table cross join
 10    table(cast(multiset(select level from dual
 11                        connect by level <= 12
 12                       ) as sys.odcinumberlist))
 13  order by id, datum;

        ID DATUM      EXCHANGERATE
---------- ---------- ------------
         1 01.01.2022          1,8
         1 01.02.2022          1,8
         1 01.03.2022          1,8
         1 01.04.2022          1,8
         1 01.05.2022          1,8
         1 01.06.2022          1,8
         1 01.07.2022          1,8
         1 01.08.2022          1,8
         1 01.09.2022          1,8
         1 01.10.2022          1,8
         1 01.11.2022          1,8
         1 01.12.2022          1,8
         2 01.01.2021          2,9
         2 01.02.2021          2,9
         2 01.03.2021          2,9
         2 01.04.2021          2,9
         2 01.05.2021          2,9
         2 01.06.2021          2,9
         2 01.07.2021          2,9
         2 01.08.2021          2,9
         2 01.09.2021          2,9
         2 01.10.2021          2,9
         2 01.11.2021          2,9
         2 01.12.2021          2,9

24 rows selected.

SQL>
mrfwxfqh

mrfwxfqh3#

其中一个选项是使用LEVEL ... CONNECT BY作为带有ADD_MONTHS()函数的生成器,如下所示:

WITH         -- Sample data
    tbl AS
      (
          Select 1 "ID", 2022 "A_DATE",  1.8 "EXCHANGE_RATE" From Dual Union All
          Select 2,      2021,           2.9                 From Dual
      )
--
--  Main SQL
Select      ID,
            To_Char(ADD_MONTHS(To_Date('01.01.' || t.A_DATE, 'dd.mm.yyyy'), (l.LVL-1) ), 'Mon-yyyy') "MONTHS", 
            EXCHANGE_RATE
From        tbl t
Inner Join  ( Select LEVEL "LVL" From Dual Connect By LEVEL <= 12) l ON(1 = 1)
Order By    t.ID, l.LVL
--
-- R e s u l t :
        ID MONTHS            EXCHANGE_RATE
---------- ----------------- -------------
         1 Jan-2022                    1.8
         1 Feb-2022                    1.8
         1 Mar-2022                    1.8
         1 Apr-2022                    1.8
        ..    ...         ....        ....
         1 Nov-2022                    1.8
         1 Dec-2022                    1.8
        -- 
         2 Jan-2021                    2.9
         2 Feb-2021                    2.9
         2 Mar-2021                    2.9
        ..    ...         ....        ....
         2 Nov-2021                    2.9
         2 Dec-2021                    2.9

相关问题