我理解这是如何运作但需要更多帮助
原始问题:
使用相关子查询为每个客户返回一行,表示客户最早的订单(具有最早日期的订单)。每行应包括这些 三列:email_address,order_id和order_date。
我的回答:
select email_address, order_id, order_date
from customers as T natural join orders
where order_date =
(select min(order_date)
from orders as S
where T.customer_id = S.customer_id
)
这些是架构:
客户:customer_id,email_address,password,first_name,last_name
订单:order_id,customer_id,order_date,ship_amount
我的理解是,我首先自然加入客户和订单。这只给了我实际订单的客户。然后我进入哪里。我接受订单表,并只选择customer_id与父项匹配的元组(但这部分对我来说似乎是多余的,因为父和子查询应该具有完全相同的customer_id)
然后从这些元组中选择min(order_date),然后检查父order_date是否等于(子查询只返回一个元组)。这意味着(根据我的理解)我的结果中只应该有一个元组(因为只有一个元组将与order_date完全匹配)
我不明白我是如何产生7个元组的(注意,我的答案显然是正确的)
感谢您的帮助
答案 0 :(得分:1)
因此,除了每个人的回答之外,我认为这有助于理解OP的问题I don't understand how having the subquery return a single tuple allows me to get more than one tuple in my final result.
想到这样......你在一个日期有多个订单。
+-------+----------------+----------------+----------------+
| id | order_date | order_quantity | email_address |
+-------+----------------+----------------+----------------+
| 1 | 5/16 | 5 |bill@win.ing |
| 2 | 5/16 | 6 |jim@win.ing |
| 3 | 5/16 | 6 |stinky@win.ing |
| 4 | 5/12 | 1 |tom@win.ing |
| 5 | 5/12 | 7 |jeremy@win.ing |
| 6 | 5/12 | 3 |silly@win.ing |
+-------+----------------+----------------+----------------+
在最近的日期有三个订单....所以当你SELECT
这样的时候。
select email_address, order_id, order_date
from customers as T natural join orders
where order_date =
(select min(order_date)
from orders as S
where T.customer_id = S.customer_id
)
这实际上说的是这个
SELECT
email_address,
order_id,
order_date
FROM customers AS T
NATURAL JOIN orders
WHERE order_date = "5/16"
正如您所看到的,5月16日表格中有多个最近日期的记录一个元组,因此将返回与其匹配的所有记录。
使用我的示例数据查询的结果将如下所示
+-------+----------------+----------------+----------------+
| id | order_date | order_quantity | email_address |
+-------+----------------+----------------+----------------+
| 1 | 5/16 | 5 |bill@win.ing |
| 2 | 5/16 | 6 |jim@win.ing |
| 3 | 5/16 | 6 |stinky@win.ing |
+-------+----------------+----------------+----------------+
KEY注意: 将返回该特定日期的所有记录
希望有助于澄清:)
答案 1 :(得分:0)
以下是对正在发生的事情的分解。
这些是您希望获得的数据列: 选择email_address,order_id,order_date
从customers表中选择数据: 来自客户的T
仅匹配已下订单的客户: 自然连接订单
以上可能更好地代表如下: 内联接订单为O ON O.customer_id = T.customer_id
这是为了获得与特定日期相匹配的订单,在这种情况下是他们的第一个订单,如果他们在同一天发出多个订单,他们会出现多次。 其中order_date = (选择min(order_date) 从订单作为S. 其中T.customer_id = S.customer_id )
如果您想通过执行以下任一操作来消除重复项:
(1)添加关键字" DISTINCT"选择后没有引号。
select DISTINCT email_address, order_id, order_date
from customers as T natural join orders
where order_date =
(select min(order_date)
from orders as S
where T.customer_id = S.customer_id
)
OR
(2)在WHERE子句
之后添加GROUP BY子句select email_address, order_id, order_date
from customers as T natural join orders
where order_date =
(select min(order_date)
from orders as S
where T.customer_id = S.customer_id
)
GROUP BY email_address, order_id, order_date
但是,您可能会发现多个order_id会获得多个customer_id,这可能是因为它们具有相同的order_date。
假设您的order_id是连续的,您可以像下面这样重写查询。
select email_address, order_id, order_date
from customers as T natural join orders
where order_id =
(select min(order_id)
from orders as S
where T.customer_id = S.customer_id
)
希望这有帮助。
答案 2 :(得分:0)
我认为这种编写方式更容易理解并以更少的冗余实现相同的结果,关键是group by
子句。
select T.email_address, S.order_id, S.order_date
from customers as T
inner join orders as S
on T.customer_id = S.customer_id
where S.order_date = (select min(S.order_date))
group by T.customer_id
为sakila示例架构格式化:
select T.email, S.rental_id, S.rental_date
from customer as T
inner join rental as S
on T.customer_id = S.customer_id
where S.rental_date = (select min(S.rental_date))
group by T.customer_id
结果集:
'MARY.SMITH@sakilacustomer.org', '76', '2005-05-25 11:30:37'
'PATRICIA.JOHNSON@sakilacustomer.org', '320', '2005-05-27 00:09:24'
[...]
599 row(s) returned
答案 3 :(得分:0)
试试这个......
select cust.email_address, o.order_id, o.order_date
from customers cust
join orders o
on cust.customer_id = o.customer_id
where order_date =
(select min(order_date)
from orders o
where cust.customer_id = o.customer_id
)