无法为我的查询找到正确的连接语句

时间:2010-12-07 04:28:11

标签: sql

我正在尝试从数据库导出数据,并使用“orders”表加入“customers”表。这是一对多关系,客户可以拥有多个订单。我正在尝试编写一个查询,该查询返回customers表中的基本客户信息 - email_address,firstname,lastname,但也包括他们放置的最后一个订单的日期。

customers as c
 - customer_id
 - firstname
 - lastname
 - email_address

orders as o
 - orders_id
 - customers_id
 - purchase_date

我希望结果为每位客户返回一个结果,其中购买日期是客户最后一次购买。

c.firstname,c.lastname,c.email_address,o.purchase_date

使这种情况发生的正确SQL语法是什么?

3 个答案:

答案 0 :(得分:1)

select c.*, o.LastOrderDate
from customers c
LEFT JOIN
(select customers_id, max(purchase_date) as LastOrderDate
from orders
group by customers_id) o on o.customers_id=c.customers_id

将获得所有客户以及最后一个订单的日期(如果存在)。

答案 1 :(得分:0)

怎么样:

SELECT c.firstname, c.lastname, c.email_address, MAX(o.purchase_date)
  FROM customers AS c
  JOIN orders    AS o ON o.customers_id = c.customer_id
 GROUP BY c.firstname, c.lastname, c.email_address

这仅列出至少下过一个订单的客户。如果您想要所有客户,那么您应该能够使用LEFT JOIN而不是简单的(INNER)JOIN,如图所示。

答案 2 :(得分:0)

这将返回所有客户,无论他们是否有任何订单:

SQL> select c.name
  2         , c.email_address
  3         , ( select max (o.order_date) from orders o
  4             where o.customer_no = c.customer_no )as last_order
  5  from   customers c
  6  /

NAME                 EMAIL_ADDRESS             LAST_ORDE
-------------------- ------------------------- ---------
ACME Industries      info@acme.com             07-APR-10
Tyrell Corporation   accounts@tyrellcorp.com   26-MAR-10
Lorax Textiles Co    the.lorax@hotmail.com

SQL>

相当于LEFT OUTER JOIN:

SQL> select c.name
  2         , c.email_address
  3         , o.last_order_date
  4  from   customers c
  5         left join ( select o.customer_no
  6                          , max (o.order_date) as last_order_date
  7                     from orders o
  8                     group by o.customer_no ) o
  9                 on o.customer_no = c.customer_no
 10  /

NAME                 EMAIL_ADDRESS             LAST_ORDE
-------------------- ------------------------- ---------
ACME Industries      info@acme.com             07-APR-10
Tyrell Corporation   accounts@tyrellcorp.com   26-MAR-10
Lorax Textiles Co    the.lorax@hotmail.com

SQL>

RIGHT OUTER JOIN只返回带有订单的客户的行。假设一个订单必须有一个客户(即强制执行的外键),那么它将与INNER JOIN相同。

如果您的数据库风格支持分析函数,那么RANK()提供了另一种解决方法......

SQL> select name
  2         , email_address
  3         , order_date
  4  from (
  5      select c.name
  6             , c.email_address
  7             , o.order_date
  8             , rank () over (partition by c.customer_no
  9                              order by o.order_date desc ) as rnk
 10      from   customers c
 11             join orders o
 12                 on ( o.customer_no = c.customer_no)
 13  )
 14  where rnk = 1
 15  /

NAME                 EMAIL_ADDRESS             ORDER_DAT
-------------------- ------------------------- ---------
ACME Industries      info@acme.com             07-APR-10
Tyrell Corporation   accounts@tyrellcorp.com   26-MAR-10

SQL>

这也仅返回带有订单的客户的行。