我是SQL的新手。我目前正在开发 Oracle数据库,我创建了一个报告,根据日期范围参数提取数据。
代码如下:
SELECT
DISTINCT C.CUSTOMER_CODE
, MS.SALESMAN_NAME
, SUM(C.REVENUE_AMT) Rev_Amt
FROM
C_REVENUE_ANALYSIS C
, M_CUSTOMER_H MC
, M_SALESMAN MS
WHERE C.COMPANY_CODE = 'W1'
AND C.CUSTOMER_CODE = MC.CUSTOMER_CODE
AND MC.SALESMAN_CODE = MS.SALESMAN_CODE
AND trunc(C.REVENUE_DATE) between to_date(<STARTDATE>,'YYYYMMDD') and to_date(<ENDDATE>,'YYYYMMDD')
AND MS.COMPANY_CODE = '00'
GROUP BY C.CUSTOMER_CODE, MS.SALESMAN_NAME
ORDER BY C.CUSTOMER_CODE, MS.SALESMAN_NAME
日期范围从1月1日到4月30日的结果报告是:
+-----------+--------------+--------------+
|Customer |Salesman Name |Revenue Amount|
+-----------+--------------+--------------+
|Customer 1 |Salesman 1 | 5000.00|
+-----------+--------------+--------------+
|Customer 2 |Salesman 1 | 8000.00|
+-----------+--------------+--------------+
|Customer 3 |Salesman 2 | 300.00|
+-----------+--------------+--------------+
|Customer 4 |Salesman 3 | 600.00|
+-----------+--------------+--------------+
|Customer 5 |Salesman 3 | 5000.00|
+-----------+--------------+--------------+
|Customer 6 |Salesman 3 | 8000.00|
+-----------+--------------+--------------+
|Customer 7 |Salesman 4 | 9000.00|
+-----------+--------------+--------------+
|Customer 8 |Salesman 5 | 2000.00|
+-----------+--------------+--------------+
|Customer 9 |Salesman 6 | 1000.00|
+-----------+--------------+--------------+
|Customer10 |Salesman 6 | 5000.00|
+-----------+--------------+--------------+
|Customer11 |Salesman 7 | 6000.00|
+-----------+--------------+--------------+
|Customer12 |Salesman 8 | 8000.00|
+-----------+--------------+--------------+
现在,我需要你的帮助。我需要在1月到4月之间显示每个销售员每个月的收入分配。
所以我希望结果如下:
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer |Salesman Name |Rev for Jan|Rev for Feb|Rev for Mar|Rev for Apr|Total Rev Amt|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 1 |Salesman 1 | 1000.00| 1000.00| 1000.00| 2000.00| 5000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 2 |Salesman 1 | 2000.00| 2000.00| 2000.00| 2000.00| 8000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 3 |Salesman 2 | 100.00| 0.00| 100.00| 100.00| 300.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 4 |Salesman 3 | 100.00| 200.00| 100.00| 200.00| 600.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 5 |Salesman 3 | 1000.00| 2000.00| 1000.00| 1000.00| 5000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 6 |Salesman 3 | 1000.00| 2000.00| 1000.00| 4000.00| 8000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 7 |Salesman 4 | 2000.00| 2000.00| 3000.00| 2000.00| 9000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 8 |Salesman 5 | 500.00| 400.00| 500.00| 600.00| 2000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer 9 |Salesman 6 | 200.00| 200.00| 200.00| 400.00| 1000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer10 |Salesman 6 | 1000.00| 1000.00| 2000.00| 1000.00| 5000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer11 |Salesman 7 | 2000.00| 2000.00| 1000.00| 1000.00| 6000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
|Customer12 |Salesman 8 | 2000.00| 2000.00| 2000.00| 2000.00| 8000.00|
+-----------+--------------+-----------+-----------+-----------+-----------+-------------+
不幸的是,由于我是新手,我无权创建存储过程以定期调用此数据。所以我可能要编写冗余代码。
但问题是,代码是什么才能分解每个销售员每月的收入?
此外,列数因日期范围而异。例如;选择1月到4月时,我会获得4列收入加1列总收入。如果选择去年10月到今年的4月份,我会获得7列收入加1列总收入。
请有人帮助新手渴望学习和证明自己吗?非常感谢你的帮助。非常感谢。
经过一番劝说后,我的经理同意提交我的存储过程以供批准,如果获得批准,则会创建。
如果我确实要创建存储过程,那么获得所需结果的代码是什么?
提前致谢。
答案 0 :(得分:0)
查看数据透视功能http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html
丑陋的部分是你必须提前知道旋转的列(在你的情况下,选择范围内的月份)。一个潜在的解决方案是使用PLSQL创建动态SQL语句,但您可能没有适当的权限来执行它。您在帖子中提到您无法创建程序(我假设您没有获得CREATE PROCEDURE授权),但不确定这是否是您唯一遗失的资助。
答案 1 :(得分:0)
案例陈述可以在总和中起作用,类似于Pivot陈述。
SELECT
DISTINCT C.CUSTOMER_CODE
, MS.SALESMAN_NAME
, SUM(C.REVENUE_AMT) Rev_Amt
,CASE WHEN
trunc(C.REVENUE_DATE) between to_date('1 jan 2014','YYYYMMDD') and to_date('31 jan 2014','YYYYMMDD')
THEN SUM(C.REVENUE_AMT)
ELSE 0
END AS Revenue_Jan_2014
FROM
C_REVENUE_ANALYSIS C
, M_CUSTOMER_H MC
, M_SALESMAN MS
WHERE C.COMPANY_CODE = 'W1'
AND C.CUSTOMER_CODE = MC.CUSTOMER_CODE
AND MC.SALESMAN_CODE = MS.SALESMAN_CODE
AND trunc(C.REVENUE_DATE) between to_date(<STARTDATE>,'YYYYMMDD') and to_date(<ENDDATE>,'YYYYMMDD')
AND MS.COMPANY_CODE = '00'
GROUP BY C.CUSTOMER_CODE, MS.SALESMAN_NAME
ORDER BY C.CUSTOMER_CODE, MS.SALESMAN_NAME
但是,正如xionutz2k的回答一样,这也需要知道具体的列。
您可以开始使用Dynamics SQL,但这可能会变得很丑陋。以下是使用Dynamic SQL的参考链接。
答案 2 :(得分:0)
另一种解决方案:
select a.cust, a.salesman,
(select sum(b.revenue) from rev b
where a.cust=b.cust and a.salesman=b.salesman and
tr_date between to_date('1 jan 2014','YYYYMMDD') and to_date('31 jan 2014')) Jan_Rev,
(select sum(c.revenue) from rev c
where a.cust=c.cust and a.salesman=c.salesman and
tr_date between to_date('1 feb 2014','YYYYMMDD') and to_date('28 feb 2014')) feb_Rev,
(select sum(d.revenue) from rev d
where a.cust=d.cust and a.salesman=d.salesman and
tr_date between to_date('1 mar 2014','YYYYMMDD') and to_date('31 mar 2014')) mar_Rev
... and so on for more months..
from
cust_table a
where
.. add where clause if any ...
答案 3 :(得分:0)
可以使用以下枢轴。通过使用EXTRACT函数将月份从收入日期中拉出,可以将其用于PIVOT并为每个月创建一列。此外,通过使用带有窗口的SUM,您可以获得每个销售员/客户组合的总收入。
需警惕的是,如果您的日期范围跨越多年,则每年的同一个月将被总计在同一列中。
例如:如果您的日期范围是2019年1月1日至2020年1月31日,则将2019年1月和2020年1月相加。
WITH
d (customer,
salesman,
revenue_amount,
revenue_date)
AS
(SELECT 'Customer 1', 'Salesman 1', 20.00, TO_DATE ('1-JAN-2020') FROM DUAL
UNION ALL
SELECT 'Customer 1', 'Salesman 1', 30.00, TO_DATE ('8-JAN-2020') FROM DUAL
UNION ALL
SELECT 'Customer 1', 'Salesman 1', 30.00, TO_DATE ('21-APR-2020') FROM DUAL
UNION ALL
SELECT 'Customer 1', 'Salesman 1', 57.00, TO_DATE ('12-JUN-2020') FROM DUAL
UNION ALL
SELECT 'Customer 1', 'Salesman 1', 76.00, TO_DATE ('1-OCT-2020') FROM DUAL
UNION ALL
SELECT 'Customer 1', 'Salesman 1', 57.00, TO_DATE ('17-MAR-2020') FROM DUAL
UNION ALL
SELECT 'Customer 2', 'Salesman 1', 12.00, TO_DATE ('3-MAY-2020') FROM DUAL
UNION ALL
SELECT 'Customer 3', 'Salesman 2', 300.00, TO_DATE ('5-APR-2020') FROM DUAL)
SELECT customer,
salesman,
NVL (jan, 0) AS rev_for_jan,
NVL (feb, 0) AS rev_for_feb,
NVL (mar, 0) AS rev_for_mar,
NVL (apr, 0) AS rev_for_apr,
NVL (may, 0) AS rev_for_may,
NVL (jun, 0) AS rev_for_jun,
NVL (jul, 0) AS rev_for_jul,
NVL (aug, 0) AS rev_for_aug,
NVL (sep, 0) AS rev_for_sep,
NVL (oct, 0) AS rev_for_oct,
NVL (nov, 0) AS rev_for_nov,
NVL (dec, 0) AS rev_for_dec,
total_revenue
FROM (SELECT d.customer,
d.salesman,
d.revenue_amount,
EXTRACT (MONTH FROM d.revenue_date) AS revenue_month,
SUM (revenue_amount) OVER (PARTITION BY d.customer, d.salesman) AS total_revenue
FROM d
WHERE revenue_date BETWEEN TO_DATE ('1-JAN-2020', 'DD-MON-YYYY')
AND TO_DATE ('30-APR-2020', 'DD-MON-YYYY'))
PIVOT (SUM (revenue_amount)
FOR revenue_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))
ORDER BY customer, salesman;
CUSTOMER SALESMAN REV_FOR_JAN REV_FOR_FEB REV_FOR_MAR REV_FOR_APR REV_FOR_MAY REV_FOR_JUN REV_FOR_JUL REV_FOR_AUG REV_FOR_SEP REV_FOR_OCT REV_FOR_NOV REV_FOR_DEC TOTAL_REVENUE
_____________ _____________ ______________ ______________ ______________ ______________ ______________ ______________ ______________ ______________ ______________ ______________ ______________ ______________ ________________
Customer 1 Salesman 1 50 0 57 30 0 0 0 0 0 0 0 0 137
Customer 3 Salesman 2 0 0 0 300 0 0 0 0 0 0 0 0 300