如何在oracle中找到丢失的行

时间:2010-04-16 02:55:46

标签: sql oracle

我有一张名为2表的表

create table ORDERS (
    ORDER_NO NUMBER(38,0) not null,
    ORDER_DATE DATE not null,
    SHIP_DATE DATE null,
    SHIPPING_METHOD VARCHAR2(12) null,
    TAX_STATUS CHAR(1) null,
    SUBTOTAL NUMBER null,
    TAX_AMT NUMBER null,
    SHIPPING_CHARGE NUMBER null,
    TOTAL_AMT NUMBER null,
    CUSTOMER_NO NUMBER(38,0) null,
    EMPLOYEE_NO NUMBER(38,0) null,
    BRANCH_NO NUMBER(38,0) null,
    constraint ORDERS_ORDERNO_PK primary key (ORDER_NO) ); 

create table PAYMENTS (
    PAYMENT_NO NUMBER(38,0) NOT NULL,       
    CUSTOMER_NO NUMBER(38,0) null,
    ORDER_NO NUMBER(38,0) null,
    AMT_PAID NUMBER NULL,
    PAY_METHOD VARCHAR(10) NULL,
    DATE_PAID DATE  NULL,
    LATE_DAYS NUMBER NULL,
    LATE_FEES NUMBER NULL,
    constraint PAYMENTS_PAYMENTNO_PK primary key (PAYMENT_NO) );

我试图找出每个客户有多少晚订单。 PAYMENTS表格中的late_days列显示客户为任何特定订单付款的延迟天数。

所以我正在进行此查询

SELECT C.CUSTOMER_NO, C.lname, C.fname, sysdate, COUNT(P.ORDER_NO) as number_LATE_ORDERS
FROM CUSTOMER C, orders o, PAYMENTS P
WHERE C.CUSTOMER_NO = o.CUSTOMER_NO
AND P.order_no = o.order_no
AND P.LATE_DAYS>0
group by C.CUSTOMER_NO, C.lname, C.fname

这意味着,我正在计算那些有延迟付款和晚了> 0的订单。但是这只给了我那些订购了晚了大于0的客户,但是没有任何延迟订单的客户没有出现。因此,如果一个客户有5个订单延迟付款,那么它为该客户显示5个订单,但如果客户有0个延迟付款,则该查询中未选择该客户。 有没有办法选择所有客户,如果他有任何延迟订单,它会显示数字,如果他没有任何延迟订单,它将显示0。

3 个答案:

答案 0 :(得分:2)

我会提取所有客户/订单/付款,然后根据late_days字段确定您选择的延迟订单数量。这假设每个订单行只有1个延迟付款行。

select c.customer_no, 
       c.lname, 
       c.fname, 
       sysdate,
       sum(case when p.late_days > 0 then 1
                else 0
       end) number_late_orders
  from customer c, 
       orders o, 
       payments p
 where c.customer_no = o.customer_no
   and p.order_no = o.order_no
group by c.customer_no, 
         c.lname, 
         c.fname

答案 1 :(得分:0)

您是否有没有订单的客户,如果有,您是否想要展示它们? 我会假设“不”或“是和否”。

SELECT C.CUSTOMER_NO, C.lname, C.fname, sysdate, COUNT(P.ORDER_NO) as number_LATE_ORDERS
FROM CUSTOMER C 
  join orders o on C.CUSTOMER_NO = o.CUSTOMER_NO
  left outer join PAYMENTS P on P.order_no = o.order_no and P.LATE_DAYS>0
group by C.CUSTOMER_NO, C.lname, C.fname

答案 2 :(得分:0)

一个内部连接和一个外部连接应该可以解决问题。我没有对它进行过测试,但我认为没有计算NULL值,因此所有有订单的客户都会显示,但只有具有late_days>的付款。 0将有条目,可以计算。那些在子选择中没有结果的客户将在p.order_no中产生一个NULL条目,其COUNT()函数不应该计算。

SELECT C.CUSTOMER_NO, C.lname, C.fname, sysdate, COUNT(P.ORDER_NO) as number_LATE_ORDERS
FROM CUSTOMER C 
INNER JOIN orders o ON (C.CUSTOMER_NO = o.CUSTOMER_NO) 
LEFT OUTER JOIN (SELECT * FROM PAYMENTS WHERE p.late_days > 0) P ON (P.order_no = o.order_no)
GROUP by C.CUSTOMER_NO, C.lname, C.fname