如何执行仅使用 SQL 索引月份的 for 循环
How to perform a for loop indexing the month with SQL only
我正在尝试按月查询销量,因此我尝试每个月制作 12 列。到目前为止,我写了 12 行,每个月一行,但我想用一个 for 循环来优化它,索引月份数 ('01','02','03',...,'12')
,如果可能的话,只用 SQL(我的数据库是一个Oracle 12c
)。这是我的代码的 MWE:
select
a.client,
round(sum(decode(to_char(a.data,'mm'), '01', a.sales)), 2) as jan,
round(sum(decode(to_char(a.data,'mm'), '02', a.sales)), 2) as feb,
round(sum(decode(to_char(a.data,'mm'), '03', a.sales)), 2) as mar,
round(sum(decode(to_char(a.data,'mm'), '04', a.sales)), 2) as apr,
round(sum(decode(to_char(a.data,'mm'), '05', a.sales)), 2) as may,
round(sum(decode(to_char(a.data,'mm'), '06', a.sales)), 2) as jun,
round(sum(decode(to_char(a.data,'mm'), '07', a.sales)), 2) as jul,
round(sum(decode(to_char(a.data,'mm'), '08', a.sales)), 2) as aug,
round(sum(decode(to_char(a.data,'mm'), '09', a.sales)), 2) as sep,
round(sum(decode(to_char(a.data,'mm'), '10', a.sales)), 2) as oct,
round(sum(decode(to_char(a.data,'mm'), '11', a.sales)), 2) as nov,
round(sum(decode(to_char(a.data,'mm'), '12', a.sales)), 2) as dez
from salesmov a,
clients b
where 1e1 = 1e1
and a.codcli = b.codcli
group by a.client
;
SQL 没有 FOR
循环。
您可以使用 PIVOT
语句将 SUM
聚合应用于所有被透视的列:
SELECT *
FROM (
SELECT client,
EXTRACT(MONTH FROM "DATE") AS month,
ROUND(sales, 2) As sales
FROM salesmov a
WHERE EXISTS(SELECT 1 FROM clients b WHERE a.codcli = b.codcli)
)
PIVOT (
SUM(sales) FOR month IN (
1 AS jan, 2 AS feb, 3 AS mar, 4 AS apr, 5 AS may, 6 AS jun,
7 AS jul, 8 AS aug, 9 AS sep, 10 AS oct, 11 As nov, 12 AS dec
)
)
其中,对于示例数据:
CREATE TABLE salesmov (client, "DATE", sales, codcli) AS
SELECT 1, ADD_MONTHS(DATE '2022-01-01', LEVEL - 1), 100 * LEVEL, 1
FROM DUAL
CONNECT BY LEVEL <= 12 UNION ALL
SELECT 2, ADD_MONTHS(DATE '2022-01-01', LEVEL - 1), 25 * LEVEL, 1
FROM DUAL
CONNECT BY LEVEL <= 12;
CREATE TABLE clients (codcli) AS
SELECT 1 FROM DUAL;
输出:
CLIENT
JAN
FEB
MAR
APR
MAY
JUN
JUL
AUG
SEP
OCT
NOV
DEC
1
100
200
300
400
500
600
700
800
900
1000
1100
1200
2
25
50
75
100
125
150
175
200
225
250
275
300
db<>fiddle here
我正在尝试按月查询销量,因此我尝试每个月制作 12 列。到目前为止,我写了 12 行,每个月一行,但我想用一个 for 循环来优化它,索引月份数 ('01','02','03',...,'12')
,如果可能的话,只用 SQL(我的数据库是一个Oracle 12c
)。这是我的代码的 MWE:
select
a.client,
round(sum(decode(to_char(a.data,'mm'), '01', a.sales)), 2) as jan,
round(sum(decode(to_char(a.data,'mm'), '02', a.sales)), 2) as feb,
round(sum(decode(to_char(a.data,'mm'), '03', a.sales)), 2) as mar,
round(sum(decode(to_char(a.data,'mm'), '04', a.sales)), 2) as apr,
round(sum(decode(to_char(a.data,'mm'), '05', a.sales)), 2) as may,
round(sum(decode(to_char(a.data,'mm'), '06', a.sales)), 2) as jun,
round(sum(decode(to_char(a.data,'mm'), '07', a.sales)), 2) as jul,
round(sum(decode(to_char(a.data,'mm'), '08', a.sales)), 2) as aug,
round(sum(decode(to_char(a.data,'mm'), '09', a.sales)), 2) as sep,
round(sum(decode(to_char(a.data,'mm'), '10', a.sales)), 2) as oct,
round(sum(decode(to_char(a.data,'mm'), '11', a.sales)), 2) as nov,
round(sum(decode(to_char(a.data,'mm'), '12', a.sales)), 2) as dez
from salesmov a,
clients b
where 1e1 = 1e1
and a.codcli = b.codcli
group by a.client
;
SQL 没有 FOR
循环。
您可以使用 PIVOT
语句将 SUM
聚合应用于所有被透视的列:
SELECT *
FROM (
SELECT client,
EXTRACT(MONTH FROM "DATE") AS month,
ROUND(sales, 2) As sales
FROM salesmov a
WHERE EXISTS(SELECT 1 FROM clients b WHERE a.codcli = b.codcli)
)
PIVOT (
SUM(sales) FOR month IN (
1 AS jan, 2 AS feb, 3 AS mar, 4 AS apr, 5 AS may, 6 AS jun,
7 AS jul, 8 AS aug, 9 AS sep, 10 AS oct, 11 As nov, 12 AS dec
)
)
其中,对于示例数据:
CREATE TABLE salesmov (client, "DATE", sales, codcli) AS
SELECT 1, ADD_MONTHS(DATE '2022-01-01', LEVEL - 1), 100 * LEVEL, 1
FROM DUAL
CONNECT BY LEVEL <= 12 UNION ALL
SELECT 2, ADD_MONTHS(DATE '2022-01-01', LEVEL - 1), 25 * LEVEL, 1
FROM DUAL
CONNECT BY LEVEL <= 12;
CREATE TABLE clients (codcli) AS
SELECT 1 FROM DUAL;
输出:
CLIENT JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC 1 100 200 300 400 500 600 700 800 900 1000 1100 1200 2 25 50 75 100 125 150 175 200 225 250 275 300
db<>fiddle here