我试图相互减去日期
问题是我必须创建一个查询来显示订购后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
答案 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;