0
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。

4

3 回答 3

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;

SQL 演示

于 2013-02-18T22:58:00.773 回答
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

感觉很痛苦。

于 2013-02-18T23:13:44.273 回答
0

不确定您的预期输出,但这是我的版本 - 您将看到 ctype = CASH 的每一行的最后付款日期。您可以在主查询中使用 WHERE 限制输出。您可以使用 LAG() 填充空白等... 270 与 CASH 最大日期是 12/13/2011,而不是这个日期 1/11/2012 bcs ctype = INV in 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
/
于 2013-02-19T16:20:08.763 回答