Oracle查找是否在几天内存在相应的记录

时间:2015-04-19 10:57:29

标签: sql oracle date-arithmetic

我试图相互减去日期

问题是我必须创建一个查询来显示订购后30天内未发货的订单。

这是我的尝试:

select orderno 
from orders 
where 30> (select datediff(dd,s.ship_date,o.odate ) 
           from o.orders,s.shipment);

我得到的错误是

  

第1行的错误:
  ORA-00942:表或视图不存在

这是两个表:

SQL> desc orders

Name                                      Null?    Type
----------------------------------------- -------- ----------------------------

ORDERNO                                   NOT NULL NUMBER(3)
ODATE                                     NOT NULL DATE
CUSTNO                                             NUMBER(3)
ORD_AMT                                            NUMBER(5)

SQL> desc shipment
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------

ORDERNO                                   NOT NULL NUMBER(3)
WAREHOUSENO                               NOT NULL VARCHAR2(3)
SHIP_DATE                                          DATE

3 个答案:

答案 0 :(得分:3)

你想要的东西是:

select ...
from   orders o
where  not exists (
         select null
         from   shipments s
         where  s.orderno   = o.orderno
         and    s.ship_date <= (o.odate + 30))

如果您只想要天数差异,则日期算术非常简单,因为您可以将天数作为整数加或减。如果是几个月,几个季度或几年你想要使用Add_Months()。

此外,在上面的查询中更好地说“shipment_date&lt; =(order_date + 30)”而不是“(shipment_date - order_date)&lt; = 30)”,因为它允许在连接键和装运上使用索引日期合并。在实践中,您可能需要(s.orderno,s.ship_date)上的索引,以便不必为此查询访问货件表。

我在这里使用了NOT EXISTS,因为如果每个订单可能有多个货件,您会希望查询在找到单个货物时停止查找其他货件。

答案 1 :(得分:1)

您的语法错误,并且您试图隐含地进行交叉连接。我认为你需要的是一个INNER JOIN,我假设它将返回一行(如果它返回多行然后使用&gt; ALL),如:

select orderno 
from orders 
where 30> (select s.ship_date - o.odate 
           from orders o INNER JOIN shipment s
           ON o.orderNo = s.orderNo);

答案 2 :(得分:1)

以下是一种使用Oracle语法的方法:

select o.orderno
from orders o
where 30 > (select o.date - s.ship_date
            from shipment s
            where s.orderno = o.orderno
           );

请注意子查询中的关联子句,但每个表只提一次。

您遇到的问题是,订单可能会在某些情况下发布 - 这会在查询中生成错误,因为子查询将返回多行。一种解决方案是聚合。您需要确定问题是否为&#34;整个订单未在30天内发货&#34;或者&#34;订单中没有任何部分在30天内发货&#34;。后者将使用MIN()

select o.orderno
from orders o
where (select MIN(o.date - s.ship_date)
       from shipment s
       where s.orderno = o.orderno
      ) > 30;