CREATE TABLE PAYMENTS
(
CTRL_NO NUMBER NOT NULL,
CUSTOMER_NO NUMBER NOT NULL,
CTYPE VARCHAR2(10 BYTE) NOT NULL,
AMOUNT NUMBER,
PAYMENT_DATE DATE
)
CREATE UNIQUE INDEX TEST1_PK ON PAYMENTS
(CTRL_NO)
ALTER TABLE PAYMENTS ADD (
CONSTRAINT TEST1_PK
PRIMARY KEY
(CTRL_NO)
USING INDEX
Insert into PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(266, 272, 'CASH', -47, TO_DATE('12/09/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(286, 272, 'CASH', 47, TO_DATE('12/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(701, 272, 'CASH', -200, TO_DATE('12/13/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(752, 272, 'INV', -91, TO_DATE('01/11/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(307, 252, 'AUTO', -9.35, TO_DATE('12/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(126, 252, 'AUTO', -128, TO_DATE('12/05/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(86, 252, 'INV', -18, TO_DATE('12/05/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(5890, 400, 'CASH', 120, TO_DATE('03/07/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(5888, 400, 'CASH', 76.41, TO_DATE('03/07/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(5886, 400, 'CASH', 86.34, TO_DATE('03/07/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(5680, 400, 'CASH', 158.97, TO_DATE('03/06/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(5819, 400, 'CASH', -40.94, TO_DATE('03/06/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into .PAYMENTS
(CTRL_NO, CUSTOMER_NO, CTYPE, AMOUNT, PAYMENT_DATE)
Values
(718, 400, 'INV', -40.04, TO_DATE('12/21/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'));
COMMIT;
我想获得最后一笔现金交易的金额(金额)。如果没有,那么只需返回0。
这是我到目前为止的查询:
select p1.customer_no, max( p1.payment_date ) ,
( select nvl(sum(p2.amount), 0)
from payments p2
where p2.ctype = 'CASH'
and p2.customer_no = p1.customer_no
) as last_payment_date
from payments p1
group by p1.customer_no
order by p1.customer_no ;
问题是272应该是11-jan-12 -200,但上面的查询返回13-dec-11 -200。另外,我应该得到400 7-mar-12 282.75而不是400.78。
答案 0 :(得分:1)
试试这个
WITH CTE AS
(
select p1.customer_no, max(p1.payment_date) max_dt
from payments p1
group by p1.customer_no
), CTE2 AS
(
select A.customer_no, sum(A.amount) amount
from payments A
WHERE ctype = 'CASH'
AND payment_date = (SELECT max(x.payment_date)
FROM payments X WHERE X.ctype = 'CASH'
AND A.customer_no = X.customer_no)
group by A.customer_no
)
SELECT A.customer_no, A.max_dt, nvl(amount,0) amount
FROM CTE A
LEFT OUTER JOIN CTE2 B
ON A.customer_no = B.customer_no
ORDER BY A.customer_no;
答案 1 :(得分:0)
select p1.customer_no, max( p1.payment_date ) , 0
from payments p1
where not exists ( select 1 from payments p2 where p2.customer_no = p1.customer_no and ctype = 'CASH' )
group by p1.customer_no
union
select p1.customer_no, payment_date, nvl(sum(amount),0)
from payments p1 inner join ( select customer_no, max(payment_date ) as max_date from payments where ctype = 'CASH' group by customer_no ) subQ
on ( p1.customer_no = subQ.customer_no
and p1.payment_date = subQ.max_date
)
group by p1.payment_date, p1.customer_no
感觉很痛苦。
答案 2 :(得分:0)
不确定您的预期输出,但这是我的版本 - 您将看到针对ctype = CASH的每一行的最后付款日期。您可以使用主查询中的WHERE限制输出。您可以使用LAG()填充空白等... 270 CASH最大日期是12/13/2011,而不是这个日期1/11/2012 bcs ctype = INV在JAN。你有疑问。插入值时出错了。希望它有所帮助:
SELECT customer_no
, ctype
, amount
, payment_date
, ( SELECT max(payment_date)
FROM stack_test
WHERE ctype = 'CASH'
AND a.customer_no = customer_no
AND a.ctype = ctype
) last_payment_date
FROM stack_test a
/
CUSTOMER_NO CTYPE AMOUNT PAYMENT_DATE LAST_PAYMENT_DATE
-------------------------------------------------------------------
272 CASH -47 12/9/2011 12/13/2011
272 CASH 47 12/12/2011 12/13/2011
272 CASH -200 12/13/2011 12/13/2011 -- This is CASH max date --
272 INV -91 1/11/2012 -- This is INV max date not CASH --
252 AUTO -9.35 12/12/2011
252 AUTO -128 12/5/2011
252 INV -18 12/5/2011
400 CASH 120 3/7/2012 3/7/2012
400 CASH 76.41 3/7/2012 3/7/2012
400 CASH 86.34 3/7/2012 3/7/2012
400 CASH 158.97 3/6/2012 3/7/2012
400 CASH -40.94 3/6/2012 3/7/2012
400 INV -40.04 12/21/2011
根据您的意见提供更多示例:
-- Max date by trans type --
SELECT ctype, max(payment_date) max_cash_date
FROM stack_test
GROUP BY ctype
ORDER BY 2
/
CTYPE MAX_CASH_DATE
-----------------------
AUTO 12/12/2011
INV 1/11/2012
CASH 3/7/2012
-- Example of using analytic functions - not needed in this case --
SELECT * FROM
(
SELECT customer_no, ctype
, MAX(payment_date) OVER (PARTITION BY ctype ORDER BY ctype) max_cash_date
, ROW_NUMBER() OVER (PARTITION BY ctype ORDER BY ctype) rno
, amount
FROM stack_test
)
-- WHERE rno=1 -- Optional - retunrns same rows as above --
ORDER BY ctype
/