简体   繁体   中英

Convert SQL query to a subquery

odd request I know. But my client likes to change his mind more than I change my pants. The following is a snippet of my SQL query:

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 

I want to convert it into a sub query. Why? Because I have a **** tonne more to add to this query and I desperately need a kick start in the world of sub queries. I attempted this:

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)

But I'm obviously not grasping the concept cause it isn't working. Please help me stackers!

Sample data set (Very Small)

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

From this small snippet, Akira has made an order, but Charlie hasn't. I am using PHP to do CSV exports and I need to display all records regardless. So my expected result would be

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

ps C.customer_ID = O.order_No are what link a customer to an order

TL;DR Answer from @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

OK, let me tear apart your example so that hopefully I can increase your knowledge and understanding.

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
  )

This is a start, but you must understand that a sub-select like this in the WHERE clause does not provide values to the result - it only qualifies which rows from the main select are included.

Notice that your WHERE clause has C.customer_ID IN which means that the sub-select must return a set of customer_ID values. Now, these can be called something else, but need to be customer_ID s. In your example, you are returning O.order_No, O.order_Date , which is wrong in two ways - first, neither seems like it would contain a customer_ID , and second, you are returning two things, which is a no go - you can't match a single customer number against a list which has two columns - think about doing this in program code - you can't say int == (Object){int,int} .

If you want these values in the resultset, they need to be selected in the main (outer) query, so they need to get there somehow, which means that a subquery probably isn't the answer - a subquery as part of the WHERE clause is for refining the resultset, for excluding some unwanted data.

Try something like this:

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

but if you MUST use a subselect, and assuming you don't need to return the order details:

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

Note also that typically one customer could have many orders, so you have to allow for that. I hope that helps. Ask questions if you need to.


EDIT Based upon the example added to the question, I think the correct query would be:

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

Here is a fiddle: http://sqlfiddle.com/#!2/ca441/1

Note that it is BAD to have customer numbers in a column named Order_No - Why isn't it Customer_ID ??? To explain, at the moment, there is no "order number", the order_No column contains customer_ID values. What happens when a client places multiple orders? Here is an example: http://sqlfiddle.com/#!2/297e1/1 and as you can see, the "order number" is the same for all orders from each client. Your orders table needs another column, customer_ID added, and order_No can then be a unique key for each order. It also then makes it obvious that the two tables should be joined on customer_ID .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM