将SQL查询转换为子查询

时间:2014-06-03 22:46:06

标签: php mysql sql subquery

奇怪的要求我知道。但我的客户喜欢改变主意,而不是改变裤子。以下是我的SQL查询的片段:

SELECT C.f_Name, C.l_Name, O.order_No, O.order_Date
FROM Customers AS C, Orders AS O,
WHERE C.customer_ID = O.order_No 

我想将其转换为子查询。为什么?因为我有更多的****吨添加到这个查询,我迫切需要在子查询的世界启动。 我试过这个:

SELECT C.f_Name, C.l_Name
FROM Customers AS C
WHERE C.customer_ID IN (SELECT O.order_No, O.order_Date FROM Orders AS O WHERE C.customer_ID = O.order_No)

但我显然没有理解这个概念,因为它不起作用。请帮我堆叠!

样本数据集(非常小)

Customers Table

customer_ID | f_Name | l_Name
10            Akira    Dawson
11            Charlie  Frantooie

Orders Table

order_No | order_Date | 
10         2014-04-11 09:04:36

从这个小片段中,晃已下订单,但查理还没有。我正在使用PHP进行CSV导出,我需要显示所有记录。所以我的预期结果将是

Customer_ID | f_Name | l_Name | order_No | order_Date
10            Akira    Dawson     10       2014-04-11
11            Charlie  Frantooie  NA          NA 

p.s C.customer_ID = O.order_No是客户与订单的链接

TL; DR 来自@Turophile的回答

SELECT C.customer_ID, C.f_Name, C.l_Name, O.order_No, O.order_Date
FROM Customers AS C
LEFT OUTER JOIN Orders AS O
ON C.customer_ID = O.order_No

1 个答案:

答案 0 :(得分:1)

好的,让我撕开你的榜样,希望我能增加你的知识和理解。

SELECT C.f_Name, C.l_Name
FROM Customers AS C
WHERE C.customer_ID IN (
  SELECT O.order_No, O.order_Date 
  FROM Orders AS O 
  WHERE C.customer_ID = O.order_No
  )

这是一个开始,但您必须明白WHERE子句中的这样的子选择不会为结果提供值 - 它只限定主要选择中包含哪些行。

请注意,您的WHERE子句有C.customer_ID IN,这意味着子选择必须返回一组customer_ID值。现在,这些可以被称为其他东西,但需要是customer_ID s。 在您的示例中,您将返回O.order_No, O.order_Date,这在两个方面是错误的 - 首先,似乎它不会包含customer_ID,其次,您返回两件事,这是不行的 - 您不能将单个客户编号与具有两列的列表相匹配 - 考虑在程序代码中执行此操作 - 您不能说int == (Object){int,int}

如果你想在结果集中使用这些值,则需要在主(外部)查询中选择它们,因此它们需要以某种方式到达那里,这意味着子查询可能不是答案 - 子查询作为WHERE子句用于优化结果集,用于排除一些不需要的数据。

尝试这样的事情:

SELECT C.f_Name, C.l_Name, order_No, O.order_Date
FROM Customers AS C
LEFT OUTER JOIN Orders AS O
ON C.customer_ID = O.customer_ID

但如果您必须使用子选择,并假设您不需要返回订单详细信息:

SELECT C.f_Name, C.l_Name
FROM Customers AS C
WHERE C.customer_ID IN (SELECT O.customer_ID  FROM Orders)

另请注意,通常一个客户可能有很多订单,因此您必须允许这样做。 我希望有所帮助。如果需要,可以提出问题。


编辑根据添加到问题中的示例,我认为正确的查询将是:

SELECT C.customer_ID, C.f_Name, C.l_Name, O.order_No, O.order_Date
FROM Customers AS C
LEFT OUTER JOIN Orders AS O
ON C.customer_ID = O.order_No

这是一个小提琴:http://sqlfiddle.com/#!2/ca441/1

请注意,在名为Order_No的列中包含客户编号是不可取的 - 为什么不是Customer_ID ???为了解释,目前没有“订单号”,order_No列包含customer_ID值。当客户发出多个订单时会发生什么?下面是一个示例:http://sqlfiddle.com/#!2/297e1/1,正如您所看到的,每个客户的所有订单的“订单号”都是相同的。您的订单表需要添加另一列customer_ID,然后order_No可以是每个订单的唯一键。然后,它显然应该在customer_ID上加入两个表。