Sql 为我的查询找到正确的join语句时遇到问题

Sql 为我的查询找到正确的join语句时遇到问题,sql,Sql,我试图从数据库导出数据,并将“customers”表与“orders”表连接起来。这是一种一对多的关系,客户可以有多个订单。我试图编写一个查询,从customers表返回基本的客户信息-email_address、firstname、lastname,但也包括他们下的最后一个订单的日期 customers as c - customer_id - firstname - lastname - email_address orders as o - orders_id - custo

我试图从数据库导出数据,并将“customers”表与“orders”表连接起来。这是一种一对多的关系,客户可以有多个订单。我试图编写一个查询,从customers表返回基本的客户信息-email_address、firstname、lastname,但也包括他们下的最后一个订单的日期

customers as c
 - customer_id
 - firstname
 - lastname
 - email_address

orders as o
 - orders_id
 - customers_id
 - purchase_date
我希望结果为每个客户返回一个结果,其中购买日期是客户进行的最后一次购买

c、 姓氏,c.姓氏,c.电子邮件地址,o.购买日期

实现这一点的正确SQL语法是什么

那么:

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
这仅列出至少下过一次订单的客户。如果您想要所有客户,那么您应该能够使用左连接,而不是如图所示的简单(内部)连接

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

将获取所有客户和上次订单的日期(如果存在)。

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

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>
它相当于左外连接:

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>
右外部联接只会为有订单的客户返回行。假设订单必须有客户(即强制外键),则这与内部联接相同

如果您喜欢的数据库支持分析函数,那么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>

这也只会为有订单的客户返回行。

如果找不到有效的右连接,也许您应该尝试使用左连接来代替。如果客户没有下任何订单,会发生什么情况?是否有与客户无关的订单?您的意思是“正确加入”还是“正确加入”?