Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-14 : 18:14:47
|
| I am very new to SQL Server, working with it in class. I am trying to do procedures involving subqueries using the Northwind database, and am having a rough time. For instance, I have the following code, which lists all orders for the month of November, 1996:SELECT Customers.CustomerID, Customers.CompanyName, CAST(Orders.OrderDate AS CHAR (11) )AS OrderDateFROM Customers, OrdersWHERE Customers.CustomerID = Orders.CustomerIDAND OrderDate BETWEEN '11/1/1996' AND '11/30/1996' ;I have been asked to do the same thing, but using a subquery. I came up with the following:SELECT CustomerID, CompanyName FROM Customers aWHERE EXISTS (SELECT OrderDate FROM Orders b WHERE a.CustomerID = b.CustomerID AND OrderDate BETWEEN '11/1/1996' AND '11/30/1996' ) ;However, it does not list the Order Date, as I want it to, and the information is not correct (it is missing a few orders from November '97 that should show up. Can someone tell me what I am doing incorrectly?Please note that I do not need anyone to give me the code, but simply give me an idea of what I am doing incorrectly, or let me know how it can be done, so that I may do it. =-) |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-01-14 : 18:44:28
|
quote: Please note that I do not need anyone to give me the code, but simply give me an idea of what I am doing incorrectly, or let me know how it can be done, so that I may do it. =-)
Ahh - How refreshing! Good for you.Couple things:- In the second statement you are just selecting out of the customer table so it is impossible to get an order date and you won't be able to return the same customer for multiple rows. All you are doing is using the Orders table to check for existance of the customer. So if the customer had 100 orders within the date range or just one doesn't matter. You will only get 1 row per customer. You'll notice that the missing rows are multiple orders for the same customer.- notice also that the column list in the SELECT statement of the subquery has no impact on the results. You can change to: "select 'Caldrumr'.." and you will get the same results. That is the nature of "where exists" clauses. The correlation between the inner and outer queries is what the "exists" works on.So you will need another tact to return the same results using a subquery. And a subquery doesn't have to be a WHERE EXISTS.Be One with the OptimizerTG |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-14 : 18:58:18
|
| Okay. Well, if I add the select for the order date to the original SELECT statement, I will be going back to the original code, not making the subquery it asks for.I understand what you mean about why I am not getting all the results I need now: it is only listing each customer once, ignoring multiple orders, which accounts for the four or so missing orders.But I'm afraid I'm stuck on how to continue here... The book really doesn't seem to give me much help, and I have been looking for information online, but I cannot seem to find anything that ties in with what I need to do here. I am confused as how to do what it is asking.They want me to list all of the orders for November, 2006 using a subquery. I will, of course, need to list the order and their dates... I am not sure how I can do this with a subquery. I am stuck.Thank you very much for your time. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-01-14 : 19:20:45
|
| >>Thank you very much for your time.You're very welcome.Well, the best way to do this is the way you did initially using an inner join. Although in the industry these days it would be preferred to use the newer JOIN syntax rather than the comma seperated list of tables. So I think the request to use a subquery just for "subquerying" sake is not a good idea. But just to satisfy the requirement, you know you need to select out of the orders table because that is where all the detail is. The only other thing you need is the customer name (customer table). So I see three possibilites: you could either simply reverse your logic (use where exists from the customer table) or make your subquery a derived table - which is a subquery in the FROM clause instead of the where clause. Or third option is to use a subquery right in the SELECT statement to define the CustomerName value.Be One with the OptimizerTG |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-14 : 19:29:56
|
quote: Originally posted by TG >>Thank you very much for your time.You're very welcome.Well, the best way to do this is the way you did initially using an inner join. Although in the industry these days it would be preferred to use the newer JOIN syntax rather than the comma seperated list of tables. So I think the request to use a subquery just for "subquerying" sake is not a good idea. But just to satisfy the requirement, you know you need to select out of the orders table because that is where all the detail is. The only other thing you need is the customer name (customer table). So I see three possibilites: you could either simply reverse your logic (use where exists from the customer table) or make your subquery a derived table - which is a subquery in the FROM clause instead of the where clause. Or third option is to use a subquery right in the SELECT statement to define the CustomerName value.Be One with the OptimizerTG
Okay, I had thought of putting the subquery in the select statement. That is the only thing I have tried so far. Here is what I did:SELECT CustomerID, (SELECT OrderDate FROM Orders b WHERE a.CustomerID = b.CustomerID AND b.OrderDate BETWEEN '11/1/1996' AND '11/30/1996') AS OrderDate, CompanyName FROM Customers a ;However, I may just be messing it up even further. It gives me an error, instead of returning what I need. I will try the other ways you have mentioned, and get back to you. This is really getting frustrating. |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-14 : 19:39:54
|
| Okay, I took what you said, and reversed the WHERE EXISTS. I got this:SELECT CustomerID, OrderDate FROM Orders aWHERE EXISTS (SELECT CompanyName FROM Customers b WHERE a.CustomerID = b.CustomerID AND a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996') ; This returns all the correct results! =-) Thank you so much. Was I not getting everything because it was looking in the wrong table?Now, the only problem I have is that I need it to list the Company Name as well, but that does not show up. I only get the CustomerID and OrderDate. Thank you so much for all of your time. It is very much appreciated. =-) |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-01-14 : 19:54:55
|
quote: is really getting frustrating.
We never decided on a "safe word" for you to use that will make me stop torturing you If you want an actual answer, just work "Mango" into a sentence.Your attempt to put the subquery into the SELECT clause was close, you just forgot to make a complete select statement without the subquery:ie SELECT column1, column2FROM someTableWhere some criteriaThen once you have a working statement you can add a new column3 to the SELECT like:,Column3 = (select customerName from customer where customerID = orders.customerid)Be One with the OptimizerTG |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-14 : 19:59:47
|
quote: Originally posted by TG
quote: is really getting frustrating.
We never decided on a "safe word" for you to use that will make me stop torturing you If you want an actual answer, just work "Mango" into a sentence.Your attempt to put the subquery into the SELECT clause was close, you just forgot to make a complete select statement without the subquery:ie SELECT column1, column2FROM someTableWhere some criteriaThen once you have a working statement you can add a new column3 to the SELECT like:,Column3 = (select customerName from customer where customerID = orders.customerid)Be One with the OptimizerTG
LOL, I'm sorry. I'm trying to figure things out without having anyone do it for me, but I am just getting stumped. The material in the class does not seem (to me) to prepare me for what they ask me to do. I want to figure it out, but I just keep coming up blank. I am sorry to keep asking over and over.Let me see what I can do with what you have provided. Thank you again. =-) |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-14 : 20:11:15
|
| Okay, I'm afraid this whole section is just driving me crazy. I am close to giving up here. And this is just one question out of ten; I won't have any hair left after I pull it out. I tried to change it how you said and got:SELECT CustomerID, CAST(OrderDate AS CHAR (11) )AS OrderDate FROM Orders aWHERE a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996'AND EXISTS (SELECT CompanyName FROM Customers b WHERE a.CustomerID = b.CustomerID ) ;However, this still does not list the Company Name. I am not sure what to do. And looking at later questions, I think I am in a whole lot of trouble this time.... |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-01-15 : 04:10:59
|
quote: Originally posted by Caldrumr Okay, I'm afraid this whole section is just driving me crazy. I am close to giving up here. And this is just one question out of ten; I won't have any hair left after I pull it out. I tried to change it how you said and got:SELECT CustomerID, CAST(OrderDate AS CHAR (11) )AS OrderDate FROM Orders aWHERE a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996'AND EXISTS (SELECT CompanyName FROM Customers b WHERE a.CustomerID = b.CustomerID ) ;However, this still does not list the Company Name. I am not sure what to do. And looking at later questions, I think I am in a whole lot of trouble this time....
You are almost there. Just remember that whatever detail you want need to be in select list and also make sure you add condition which checks whether details are actually present in related table. Keeping this in mind, look into bol for clauses which you think you can use to achieve it. |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-15 : 15:53:37
|
quote: You are almost there. Just remember that whatever detail you want need to be in select list and also make sure you add condition which checks whether details are actually present in related table. Keeping this in mind, look into bol for clauses which you think you can use to achieve it.
I have no idea if I am even close or not... if I add the other item to the select list, I put:SELECT a.CustomerID, CAST(a.OrderDate AS CHAR (11) )AS OrderDate, b.CompanyName FROM Orders a, Customers bWHERE EXISTS (SELECT CompanyName FROM Customers b WHERE a.CustomerID = b.CustomerID AND a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996') ;However, this brings up 2,275 rows, where there should be 25. It is showing every single company with a row for each customer and order date. I have no idea what you mean by checking whether details or present, and I don't know what looking into bol for clauses means. =-( |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-15 : 17:38:19
|
| I think I may have figured out part of it. I changed my code to:SELECT a.CustomerID, CAST(a.OrderDate AS CHAR (11) )AS OrderDate FROM Orders aJOIN Customers b ON a.CustomerID = b.CustomerID WHERE EXISTS (SELECT CompanyName FROM Customers b WHERE a.CustomerID = b.CustomerID AND a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996') ; This at least returns all the 25 rows that should exist. However, I still cannot figure out how to do this and also add CompanyName in the SELECT that shows up in the results. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-01-15 : 17:53:48
|
MANGO! MANGO!Ok that is a little overkill. But all you need is to add ",b.companyname" to your select list.--as we determined earlier this is the correct way get that info (no subquery)SELECT a.CustomerID ,CAST(a.OrderDate AS CHAR (11) ) AS OrderDate ,companyNameFROM Orders aJOIN Customers b ON a.CustomerID = b.CustomerID where a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996'--However, just to satisfy the stupid requirement of how could you do it with a sub-query--This is what I was hinting towards in my post from (01/14/2008 : 19:54:55)SELECT a.CustomerID ,CAST(a.OrderDate AS CHAR (11) ) AS OrderDate ,companyName = (select companyname from customers where customerid = a.customerid)FROM Orders awhere a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996' EDIT:I guess the date - time will post different depending on where you are so forget the "in my post from (01/14/2008 : 19:54:55)"quote: We never decided on a "safe word" for you to use that will make me stop torturing you If you want an actual answer, just work "Mango" into a sentence.Your attempt to put the subquery into the SELECT clause was close, you just forgot to make a complete select statement without the subquery:ie SELECT column1, column2FROM someTableWhere some criteriaThen once you have a working statement you can add a new column3 to the SELECT like:,Column3 = (select customerName from customer where customerID = orders.customerid)
Be One with the OptimizerTG |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-15 : 19:04:10
|
quote: Originally posted by TG MANGO! MANGO!Ok that is a little overkill. But all you need is to add ",b.companyname" to your select list.--as we determined earlier this is the correct way get that info (no subquery)SELECT a.CustomerID ,CAST(a.OrderDate AS CHAR (11) ) AS OrderDate ,companyNameFROM Orders aJOIN Customers b ON a.CustomerID = b.CustomerID where a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996'--However, just to satisfy the stupid requirement of how could you do it with a sub-query--This is what I was hinting towards in my post from (01/14/2008 : 19:54:55)SELECT a.CustomerID ,CAST(a.OrderDate AS CHAR (11) ) AS OrderDate ,companyName = (select companyname from customers where customerid = a.customerid)FROM Orders awhere a.OrderDate BETWEEN '11/1/1996' AND '11/30/1996' EDIT:I guess the date - time will post different depending on where you are so forget the "in my post from (01/14/2008 : 19:54:55)"quote: We never decided on a "safe word" for you to use that will make me stop torturing you If you want an actual answer, just work "Mango" into a sentence.Your attempt to put the subquery into the SELECT clause was close, you just forgot to make a complete select statement without the subquery:ie SELECT column1, column2FROM someTableWhere some criteriaThen once you have a working statement you can add a new column3 to the SELECT like:,Column3 = (select customerName from customer where customerID = orders.customerid)
Be One with the OptimizerTG
Well, I have to say that works absolutely perfectly. Thank you very much for the mangos... I do love a good fruit salad. ;-)Hopefully I can apply this to my other questions.I think my biggest problem was that the text did not really prepare me, which has pretty much been the case the whole term. It has all queries that only draw from one table, so I couldn't figure out how to add a field from another table. It has nothing even remotely like the "companyName = " part you have here, which is probably why I couldn't figure it out.Thank you very much. I will attempt to apply this knowledge to the other questions. Hopefully I can figure them all out now. Thank you again for all of your time and trouble. |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-15 : 19:45:10
|
| Since this is the only place I was able to get any help (talking to the professor yields me either nothing, or answers that don't work or make no sense), perhaps I can ask about a couple more items that don't make much sense to me.I have another question that wants me to convert into a subquery. The original code is:SELECT a.EmployeeID, a.LastName, a.FirstName, b.LastName AS SupervisorLast, b.FirstName AS SupervisorFirstFROM Employees a, Employees bWHERE a.ReportsTo = b.EmployeeIDORDER BY a.EmployeeID ;This takes all employees, references the same table as a virtual second table, and lists the supervisors based on matchning the EmployeeID with the ReportsTo section. This week, however, it wants me to do this using a horrible subquery. What I came up with was:SELECT a.EmployeeID, a.LastName, a.FirstName FROM Employees aWHERE EXISTS ( SELECT b.LastName AS SupervisorLast, b.FirstName AS SupervisorFirstFROM Employees b WHERE a.ReportsTo = b.EmployeeID )ORDER BY a.EmployeeID ;This, of course, does not work. I tried to do something with an equals like the first one, but I can't get it to work. Anyone have an idea how I should go about this?Also, one other question I am stuck on also includes dates. It wants me to list products that are in stock where ordered in 1993 using the IN function. I have no idea what to do on this one; I am drawing a total blank.All of the other questions, I was able to answer, with more than a little help here on number 1. =-)If anyone has any ideas for me, they would be greatly appreciated. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-01-15 : 23:05:09
|
You can do something like this:-SELECT a.EmployeeID, a.LastName, a.FirstName, (SELECT LastName FROM Employees WHERE EmployeeID=a.ReportsTo)AS SupervisorLast, (SELECT FirstName FROM Employees WHERE EmployeeID=a.ReportsTo)AS SupervisorFirstFROM Employees aORDER BY a.EmployeeID ; |
 |
|
|
Caldrumr
Starting Member
11 Posts |
Posted - 2008-01-15 : 23:24:56
|
quote: Originally posted by visakh16 You can do something like this:-SELECT a.EmployeeID, a.LastName, a.FirstName, (SELECT LastName FROM Employees WHERE EmployeeID=a.ReportsTo)AS SupervisorLast, (SELECT FirstName FROM Employees WHERE EmployeeID=a.ReportsTo)AS SupervisorFirstFROM Employees aORDER BY a.EmployeeID ;
That would have worked perfectly, had I gotten to it in time. =-) Thank you. My professor actually finally got back to me and gave me a little help, and I ended up using this, which is pretty close to what you have:SELECT a.EmployeeID, a.LastName AS EmployeeLast, a.FirstName AS EmployeeFirst, (Select LastName + ' ' + FirstName FROM Employees b WHERE b.EmployeeID = a.ReportsTo) AS Supervisor FROM Employees a;There were a couple of other ones I had some trouble with, but I think I figured them all out. That was one tough project for me. Thankfully, I only have one more week left (finals, though! )Thank you to everyone that helped me out. I learned a lot, and I appreciate the time and assistance greatly. Thanks again! Maybe when I become more knowledgeable, I can come help some others. =-) |
 |
|
|
|
|
|
|
|