如何在oracle中选择用户选择年份的所有月份
我想用两个表进行查询。即使表格中没有记录,我也想显示用户所选年份的所有月份。不过,我无法显示所有的月份,也没有空值。请帮忙?如何在oracle中选择用户选择年份的所有月份
这里是我的查询:
SELECT spendList.NUMBER,
spendList.User,
TO_CHAR(spendList.DATE, 'Month') as Month,
spendList.AMOUNT, allowence.FUND
FROM T_EXPENDITURE spendList
LEFT JOIN T_ALLOWENCE allowence
ON spendList.DEP_NO = allowence.DEP_NO
WHERE TO_CHAR(spendList.DATE, 'YYYY') = :userYear
ORDER BY spendList.DEPARTMENT
结果一定是这样的:
NUMBER USER MONTH SPEND_AMOUNT ALLOWENCE
12345 Clerk January 123 2500
7869 Manager February 150 3000
12345 Clerk March 2500
7869 Manager April 3000
12345 Clerk May 2500
7869 Manager June 3000
12345 Clerk July 2500
7869 Manager August 3000
12345 Clerk September 2500
7869 Manager September 3000
12345 Clerk October 2500
7869 Manager Nevember 3000
12345 Clerk December 2500
我会用这导致了报告,并在报告中有前人的精力是今年所有月份。
报告会是这样:
NUMBER USER January February ... December ALLOWENCE
12345 Clerk 123 null null 2500
使用PARTITION
加入:
甲骨文设置:
CREATE TABLE T_EXPENDITURE ("NUMBER", "USER", "DATE", amount, dep_no) AS
SELECT 1, 'Clerk', DATE '2017-01-10', 50, 1 FROM DUAL UNION ALL
SELECT 1, 'Clerk', DATE '2017-01-15', 73, 1 FROM DUAL UNION ALL
SELECT 1, 'Clerk', DATE '2017-02-14', 13, 1 FROM DUAL UNION ALL
SELECT 2, 'Manager', DATE '2017-02-01', 150, 2 FROM DUAL;
CREATE TABLE T_ALLOWENCE (dep_no, fund) AS
SELECT 1, 2500 FROM DUAL UNION ALL
SELECT 1, 3000 FROM DUAL;
查询:
SELECT e."NUMBER",
e."USER",
c.month,
SUM(e.amount) AS amount,
e.fund
FROM
(
SELECT e.*, a.fund
FROM t_allowance a
INNER JOIN t_expenditure e
ON (e.dep_no = a.dep_no)
) e
PARTITION BY (e."NUMBER", e."USER", e.FUND)
RIGHT OUTER JOIN
(
SELECT ADD_MONTHS(TO_DATE(:useryear || '0101', 'YYYYMMDD'), LEVEL - 1) AS month
FROM DUAL
CONNECT BY LEVEL <= 12
) c
ON(c.month <= e."DATE" AND e."DATE" < ADD_MONTHS(c.month, 1))
GROUP BY e."NUMBER", e."USER", e.FUND, c.MONTH
ORDER BY e."NUMBER", c.MONTH;
输出:
NUMBER USER MONTH AMOUNT FUND
------ ------- ---------- ------ ----
1 Clerk 2017-01-01 123 2500
1 Clerk 2017-02-01 13 2500
1 Clerk 2017-03-01 2500
1 Clerk 2017-04-01 2500
1 Clerk 2017-05-01 2500
1 Clerk 2017-06-01 2500
1 Clerk 2017-07-01 2500
1 Clerk 2017-08-01 2500
1 Clerk 2017-09-01 2500
1 Clerk 2017-10-01 2500
1 Clerk 2017-11-01 2500
1 Clerk 2017-12-01 2500
2 Manager 2017-01-01 3000
2 Manager 2017-02-01 150 3000
2 Manager 2017-03-01 3000
2 Manager 2017-04-01 3000
2 Manager 2017-05-01 3000
2 Manager 2017-06-01 3000
2 Manager 2017-07-01 3000
2 Manager 2017-08-01 3000
2 Manager 2017-09-01 3000
2 Manager 2017-10-01 3000
2 Manager 2017-11-01 3000
2 Manager 2017-12-01 3000
查询2:
SELECT *
FROM (
SELECT "NUMBER",
"USER",
EXTRACT(MONTH FROM "DATE") AS month,
amount,
e.dep_no,
fund
FROM T_EXPENDITURE e
INNER JOIN T_ALLOWENCE a
ON (e.dep_no = a.dep_no)
WHERE EXTRACT(YEAR FROM e."DATE") = :useryear
)
PIVOT (
SUM(amount)
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
)
);
输出:HTTP://www.orafaq使用`DBA_TABLES`以产生足够的行
NUMBER USER DEP_NO FUND JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
------ ------- ------ ---- --- --- --- --- --- --- --- --- --- --- --- ---
1 Clerk 1 2500 123 13
2 Manager 2 3000 150
它给c.MONTH无效标识符错误... –
@ T.Rifle查询不会给我一个错误;请检查您是否已正确复制。我还添加了一个与您的更新报告格式相匹配的更新。今后请(a)首先提出完整的问题,而不是在出现[XY-problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)解决方案和(b)不会如此戏剧性地更改您的问题输出,因为这会使一些答案失效。 – MT0
感谢您的回答。查询2对我很好。 –
该解决方案使用WITH子句语法生成一年的所有月份的一个子查询(技术上每个月的第一天)。它假设:userYear
作为一个四位数字被传递到一个日期,然后截取yyyy
面具以获得一年中的第一天。 add_months()
用于获取剩余的月份。
通过派生每个记录的月份的第一天,将此子查询外连接到您的T_EXPENDITURE表。
with calendar as (
select add_months(trunc(to_date(:userYear,'yyyy'),'yyyy'), level-1) as mon
from dual
connect by level <=12)
SELECT to_char(calendar.mon,'MONTH') as Month,
spendList.NUMBER,
spendList.User,
spendList.AMOUNT,
allowence.FUND
FROM calendar
left join T_EXPENDITURE spendList
on trunc(spendList.DATE, 'MON') = calendar.mon
LEFT JOIN T_ALLOWENCE allowence
ON spendList.DEP_NO=allowence.DEP_NO
ORDER BY spendList.DEPARTMENT
感谢您的答案,但它给出了相同的结果。即使他们有空值,我也想显示所有月份。 –
我刚修改了查询:请再试一次。如果它仍然不起作用,您需要发布一些示例数据。 – APC
方法。 com/node/2029 –
而您正在寻找的搜索词是“日历表”或“日历视图”。 –
[如何在Oracle中填充日历表?](http://stackoverflow.com/questions/8374959/how-to-populate-calendar-table-in-oracle) –