Oracle SQL 中的最后一个订单项

Posted

技术标签:

【中文标题】Oracle SQL 中的最后一个订单项【英文标题】:Last order item in Oracle SQL 【发布时间】:2013-01-16 20:35:30 【问题描述】:

我需要在客户表和订单表之间以 1:N 的关系列出客户表中的列、第一个订单的日期和最后一个订单的所有数据。我正在使用 Oracle 10g。

最好的方法是什么?

表客户 --------------- 身份证号码 名称 VARCHAR2(200) 订阅日期 DATE 表顺序 --------------- 身份证号码 id_order NUMBER 购买日期 DATE 购买价值 NUMBER

【问题讨论】:

这些表是如何关联的? order 中的id 表是否与customer 中的id 相关? 【参考方案1】:

这是一种方法,使用row_number 函数、一次连接和聚合:

select c.*,
       min(o.purchase_date) as FirstPurchaseDate, 
       min(case when seqnum = 1 then o.id_order end) as Last_IdOrder,
       min(case when seqnum = 1 then o.purchase_date end) as Last_PurchaseDate,
       min(case when seqnum = 1 then o.purchase_value end) as Last_PurchaseValue
from Customer c join
     (select o.*,
             row_number() over (partition by o.id order by purchase_date desc) as seqnum
      from orders o
     ) o
     on c.customer_id = o.order_id
group by c.customer_id, c.name, c.subscribe_date

【讨论】:

【参考方案2】:

如何将customer 表连接到orders 表并不明显(order 是Oracle 中的保留字,因此您的表不能命名为order)。如果我们假设orders 中的id_order 连接到customer 中的id

SELECT c.id customer_id,
       c.name name,
       c.subscribe_date,
       o.first_purchase_date,
       o.id last_order_id,
       o.purchase_date last_order_purchase_date,
       o.purchase_value last_order_purchase_value
  FROM customer c
       JOIN (SELECT o.*,
                    min(o.purchase_date) over (partition by id_order) first_purchase_date,
                    rank() over (partition by id_order order by purchase_date desc) rnk
               FROM orders o) o ON (c.id = o.id_order)
 WHERE rnk = 1

【讨论】:

【参考方案3】:

我对您的字段名称感到困惑,但我会假设 ORDER.id 是 CUSTOMER 表中的 id。

最早的订单日期很容易。

select CUSTOMER.*, min(ORDER.purchase_date)
from CUSTOMER
  inner join ORDER on CUSTOMER.id = ORDER.id
group by CUSTOMER.*

要获取最后的订单数据,请再次将其加入 ORDER 表。

select CUSTOMER.*, min(ORD_FIRST.purchase_date), ORD_LAST.*
from CUSTOMER
  inner join ORDER ORD_FIRST on CUSTOMER.id = ORD_FIRST.id
  inner join ORDER ORD_LAST on CUSTOMER.id = ORD_LAST.id
group by CUSTOMER.*, ORD_LAST.*
having ORD_LAST.purchase_date = max(ORD_FIRST.purchase_date)

【讨论】:

【参考方案4】:

假设Order 表中的ID 字段实际上是Customer ID,可能是这样的:

SELECT C.*, O1.*, O2.purchase_Date as FirstPurchaseDate
FROM Customer C
LEFT JOIN 
(
  SELECT Max(purchase_date) as pdate, id
  FROM Orders
  GROUP BY id
) MaxPurchaseOrder 
  ON C.Id = MaxPurchaseOrder.Id
LEFT JOIN Orders O1 
  ON MaxPurchaseOrder.pdate = O1.purchase_date 
  AND MaxPurchaseOrder.id = O1.id
LEFT JOIN 
(
  SELECT Min(purchase_date) as pdate, id
  FROM Orders
  GROUP BY id
) MinPurchaseOrder 
  ON C.Id = MinPurchaseOrder.Id
LEFT JOIN Orders O2 
  ON MinPurchaseOrder.pdate = O2.purchase_date 
  AND MinPurchaseOrder.id = O2.id

还有sql fiddle。

【讨论】:

以上是关于Oracle SQL 中的最后一个订单项的主要内容,如果未能解决你的问题,请参考以下文章

添加 ubercart 订单项并更新订单总额

Go Web编程(无框架,自带 net/http 包)六创建订单和订单项结构及对应的表创建保存订单和订单项的函数完成去结账功能获取订单详情完成获取我的订单的函数

在 Woocommerce 3+ 中使用订单项以编程方式创建订单

使用MVC / EF总结购物车中的重复订单项

订单与订单项

mybatis关联关系