oracle查找某个天数内是否存在对应的记录
Oracle find whether a corresponding record exists within a number of days
我正在尝试相互减去日期
问题说我必须创建一个查询来显示在订购后 30 天内未发货的订单。
这是我的尝试:
select orderno
from orders
where 30> (select datediff(dd,s.ship_date,o.odate )
from o.orders,s.shipment);
我得到的错误是
ERROR at line 1:
ORA-00942: table or view does not exist
这是两个表:
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
您的语法错误,您正在尝试隐式地进行交叉连接。我认为你需要的是一个 INNER JOIN,我假设它会 return 一行(如果它 return 多行然后使用 >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);
您可能想要以下内容:
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 <= (order_date + 30)" 而不是“(shipment_date - order_date) <= 30)”,因为它允许在连接上使用索引密钥和装运日期相结合。实际上,您可能希望在 (s.orderno, s.ship_date) 上建立索引,以便此查询不必访问货件 table。
我在这里使用了 NOT EXISTS,因为在每个订单可能有多个发货的情况下,您可能希望查询在找到单个发货后停止查找其他发货。
这是一种方法,使用 Oracle 语法:
select o.orderno
from orders o
where 30 > (select o.date - s.ship_date
from shipment s
where s.orderno = o.orderno
);
注意子查询中的相关子句,但每个 table 只被提及一次。
您遇到的问题是一个订单有时会多次发货 -- 这会在查询中产生错误,因为子查询会 return 不止一行。一种解决方案是聚合。您需要确定问题是 "the entire order does not ship within 30 days" 还是 "no part of the order ships within 30 days"。后者将使用 MIN()
:
select o.orderno
from orders o
where (select MIN(o.date - s.ship_date)
from shipment s
where s.orderno = o.orderno
) > 30;
我正在尝试相互减去日期
问题说我必须创建一个查询来显示在订购后 30 天内未发货的订单。
这是我的尝试:
select orderno
from orders
where 30> (select datediff(dd,s.ship_date,o.odate )
from o.orders,s.shipment);
我得到的错误是
ERROR at line 1:
ORA-00942: table or view does not exist
这是两个表:
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
您的语法错误,您正在尝试隐式地进行交叉连接。我认为你需要的是一个 INNER JOIN,我假设它会 return 一行(如果它 return 多行然后使用 >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);
您可能想要以下内容:
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 <= (order_date + 30)" 而不是“(shipment_date - order_date) <= 30)”,因为它允许在连接上使用索引密钥和装运日期相结合。实际上,您可能希望在 (s.orderno, s.ship_date) 上建立索引,以便此查询不必访问货件 table。
我在这里使用了 NOT EXISTS,因为在每个订单可能有多个发货的情况下,您可能希望查询在找到单个发货后停止查找其他发货。
这是一种方法,使用 Oracle 语法:
select o.orderno
from orders o
where 30 > (select o.date - s.ship_date
from shipment s
where s.orderno = o.orderno
);
注意子查询中的相关子句,但每个 table 只被提及一次。
您遇到的问题是一个订单有时会多次发货 -- 这会在查询中产生错误,因为子查询会 return 不止一行。一种解决方案是聚合。您需要确定问题是 "the entire order does not ship within 30 days" 还是 "no part of the order ships within 30 days"。后者将使用 MIN()
:
select o.orderno
from orders o
where (select MIN(o.date - s.ship_date)
from shipment s
where s.orderno = o.orderno
) > 30;