我有一个查询,它给出了过去三个月的销售价值。我希望在一个查询中获取所有三个月的数据,而不是三个不同的查询。如果我给'Mar-2016',它应该显示我最近三个月的数据2016年2月,2016年1月和2015年12月。
请帮我解决这个问题。
SELECT
TO_CHAR(A.JOB_DATE , 'MON-YYYY') S_MON , NULL T_MON,
TO_CHAR(A.JOB_DATE,'MM-YYYY') MM, C.SECTION_CODE SECTION,
B.ITEM_CODE ITEM_CODE, SUM(B.MASTER_QUANTITY) SALES,
NULL TARGET
FROM
TRANSACTION_MASTER A, TRANSACTION_DETAIL B,
ITEM_SECTION C, ITEM D
WHERE
A.TRANSACTION_NUMBER = B.TRANSACTION_NUMBER
AND TO_CHAR(ADD_MONTHS(A.JOB_DATE,1), 'MON-YYYY') = 'MAR-2016'
AND A.TRANSACTION_CODE = B.TRANSACTION_CODE
AND B.ITEM_CODE = D.ITEM_CODE
AND C.SECTION_CODE = D.SECTION_CODE
AND A.TRANSACTION_CODE IN (2,4)
AND D.ITEM_STATUS = 'A'
AND C.SECTION_CODE BETWEEN :ST_CODE AND :END_CODE
GROUP BY
TO_CHAR(A.JOB_DATE, 'MON-YYYY'), TO_CHAR(A.JOB_DATE, 'MM-YYYY'),
C.SECTION_CODE, B.ITEM_CODE
UNION
SELECT
TO_CHAR(A.JOB_DATE, 'MON-YYYY') S_MON, NULL T_MON,
TO_CHAR(A.JOB_DATE, 'MM-YYYY') MM,
C.SECTION_CODE SECTION, B.ITEM_CODE ITEM_CODE,
SUM(B.MASTER_QUANTITY ) SALES, NULL TARGET
FROM
TRANSACTION_MASTER A, TRANSACTION_DETAIL B,
ITEM_SECTION C, ITEM D
WHERE
A.TRANSACTION_NUMBER = B.TRANSACTION_NUMBER
AND TO_CHAR(ADD_MONTHS(A.JOB_DATE, 2), 'MON-YYYY')= 'MAR-2016'
AND A.TRANSACTION_CODE = B.TRANSACTION_CODE
AND B.ITEM_CODE = D.ITEM_CODE
AND C.SECTION_CODE = D.SECTION_CODE
AND A.TRANSACTION_CODE IN (2,4)
AND D.ITEM_STATUS = 'A'
AND C.SECTION_CODE BETWEEN :ST_CODE AND :END_CODE
GROUP BY TO_CHAR(A.JOB_DATE , 'MON-YYYY') , TO_CHAR(A.JOB_DATE,'MM-YYYY') ,C.SECTION_CODE , B.ITEM_CODE
UNION
SELECT TO_CHAR(A.JOB_DATE , 'MON-YYYY') S_MON , NULL T_MON , TO_CHAR(A.JOB_DATE,'MM-YYYY') MM ,
C.SECTION_CODE SECTION , B.ITEM_CODE ITEM_CODE , SUM(B.MASTER_QUANTITY ) SALES , NULL TARGET
FROM TRANSACTION_MASTER A , TRANSACTION_DETAIL B , ITEM_SECTION C , ITEM D
WHERE A.TRANSACTION_NUMBER = B.TRANSACTION_NUMBER
AND TO_CHAR(ADD_MONTHS(A.JOB_DATE,3),'MON-YYYY') = 'MAR-2016'
AND A.TRANSACTION_CODE = B.TRANSACTION_CODE
AND B.ITEM_CODE = D.ITEM_CODE
AND C.SECTION_CODE = D.SECTION_CODE
AND A.TRANSACTION_CODE IN (2,4)
AND D.ITEM_STATUS = 'A'
AND C.SECTION_CODE BETWEEN :ST_CODE AND :END_CODE
GROUP BY TO_CHAR(A.JOB_DATE , 'MON-YYYY') , TO_CHAR(A.JOB_DATE,'MM-YYYY') ,C.SECTION_CODE , B.ITEM_CODE
答案 0 :(得分:0)
据我所知,在union-ed子查询中唯一不同的是WHERE子句的这一行:
AND TO_CHAR(ADD_MONTHS(A.JOB_DATE,1), 'MON-YYYY') = 'MAR-2016'
^
您正在应用的实际逻辑是(*):
and a.job_date between date '2015-12-01' and date '2016-02-29'
这可以通过参数
来推广and a.job_date between :p_start_date and last_day(add_months(:p_start_date,2))
如果日期范围内的月数也是可变的,则需要另一个参数。
和a.job_date:p_start_date和last_day(add_months(:p_start_date,:p_add_months_int))
p_add_months_int
值比范围内的月数小1:所以2
限制了三个月的范围。
如果您想通过传递结束日期来定义过去三个月的范围,请在add_months()
来电中使用负数:
and a.job_date between trunc(add_months(:p_end_date,-2)) and last_day(:p_end_date)
"如果我给'2016年3月'它应该显示我最近3个月的数据2016年2月,2016年1月和2015年12月。"
好的,正是如此,你想要的是
and a.job_date between add_months(to_date(:p_start_date, 'MON-YYYY'),-3))
and to_date(:p_start_date, 'MON-YYYY'),-1)
(*)如果您希望日期范围为2016-01-01至2016-03-31,则可能会误解ADD_MONTHS(A.JOB_DATE,1)
的内容。