Sql 为我的查询找到正确的join语句时遇到问题
我试图从数据库导出数据,并将“customers”表与“orders”表连接起来。这是一种一对多的关系,客户可以有多个订单。我试图编写一个查询,从customers表返回基本的客户信息-email_address、firstname、lastname,但也包括他们下的最后一个订单的日期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 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>
这也只会为有订单的客户返回行。如果找不到有效的右连接,也许您应该尝试使用左连接来代替。如果客户没有下任何订单,会发生什么情况?是否有与客户无关的订单?您的意思是“正确加入”还是“正确加入”?