First and foremost - it is a homework assignment, yet I am not asking for anyone to do it. Instead I need help with how to construct the query.
As part of an assignment, using the Northwind database via Microsoft Access, I have to construct this query:
The product ID, product name, and quantity ordered for all products ordered on an order taken by an employee with last name Fuller.
Now, when I construct the query in design mode, this is the code I get:
SELECT Products.ProductID, Products.ProductName, [Order Details].Quantity
FROM Products INNER JOIN ((Employees INNER JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID) INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID) ON Products.ProductID = [Order Details].ProductID
WHERE (((Employees.LastName)="Fuller"));
As I mentioned earlier, we are not allowed to use Inner Join. After scouring the text/notes thus far I can't find how to go about it. (Very new to SQL)
Would I be rewriting the FROM statement? And if so, do the SELECT and WHERE statements change?
UPDATE: Here is the code as I rewrote it:
SELECT Orders.OrderID, Orders.CustomerID, Orders.ShipCity
FROM Products, Orders, [Order Details], Employees
WHERE
Products.ProductID = [Order Details].ProductID
AND Employees.EmployeeID = Orders.EmployeeID
AND Ordes.OrderID = [Order Details].OrderID
AND Employees.LastName = "Fuller";
I'm having a sort of syntax issue though. Since the Order Details must be enclosed in brackets, it wants to ask for parameter values for what I wrote in the WHERE statement.
The requirement not to use INNER JOIN is a little peculiar and I cannot guarantee this is what was intended for your assignment.
One way to alternatively write a simplistic relationship between two tables is with an IN () subquery, the general form being:
SELECT *
FROM a_table
WHERE some_column IN (
SELECT some_related_column
FROM b_table
WHERE some_condition
)
But since you must represent columns from more than one of your 4 tables in the SELECT list, that form isn't going to work for you. Another way of not explicitly using an INNER JOIN is to use the older implicit joining syntax, in which multiple tables are listed in the FROM clause separated by commas, and their joining conditions placed in the WHERE clause instead of in ON.
The general form is:
SELECT
a_table.col1,
a_table.col2,
b_table.col1
FROM
a_table,
b_table
WHERE
a_table.some_column = b_table.some_related_column
AND some_other_conditions
It being an assignment, I will leave it to you to work out the entire statement, but yours would take a form like
SELECT
Orders.OrderID,
Orders.CustomerID
FROM
Products,
Orders,
[Order Details],
Employees
WHERE
Products.ProductID = [Order Details].ProductID
AND ... (the other table relationships)
AND Employees.LastName = 'Fuller'
Although it is functionally identical to explicit INNER JOINs, this is an older syntax, and is often discouraged nowadays. More discussion is available in this question
Related
My professor said I did not tie between tables, now I want to ask how to tie tables, this are two of my example I did incorrect.
Query2 - no ties between tables
SELECT CustomerID, CompanyName, [Order Details].UnitPrice
FROM Customers, [Order Details]
WHERE ((([Order Details].UnitPrice)>=50));
Query3 - no ties between tables
SELECT ProductID, ProductName, ShippedDate
FROM Products, Orders
where Orders.ShippedDate between ('1996-07-01') and ('1996-07-31')
ORDER BY Orders.ShippedDate;
Basically your query is missing a join conditions between the two tables. Without it, you get a cartesian products of the rows from both tables.
This is where the join syntax comes into play. For example for the second query, assuming that products and orders relate through column product_id:
select p.productid, p.productname, o.shippeddate
from products p
inner join orders o on o.product_id = p.product_id
where o.shippeddate >= '1996-07-01' and o.shippeddate < '1996-08-01'
order by o.shippeddate;
Other improvements to the query:
table aliases make the query easier to write and read
half-open intervals for date comparisons are handy: they properly handle the time portion of the dates (if any)
Suppose I have two tables.. One is customers and the other is orders. Orders has a foreign key that joins to the customers table. How should I go about returning data from both tables:
Filtered on a field in the orders table and,
Filtered on a field in the customers table?
Is using WHERE to filter after the JOIN in my SELECT statement the correct way to go, or putting in an AND within the JOIN statement? And would I have to use one method for one of the above situations and the other for the other one?
For example,
SELECT customers.customer_type, orders.grant_date
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
WHERE orders.order_id = 3;
or
SELECT customers.customer_type, orders.grant_date
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
AND orders.order_id = 3;
I guess I can summarize my questions as:
a. Which table should I pair with my FROM statement? Should it be the one which has the foreign key i.e. orders? Or does it depend on the situation?
b. How should I filter the data? With a WHERE or an AND with the JOIN? And how is one different from the other i.e. when should I use one over the other in my two situations?
It doesn't matter whether you do
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
or
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id
Which table you make the first table is up to you. Here I would make orders the first table, because it is orders along with their customer information you are showing in your results.
With an inner join it doesn't make a difference either, whether you put criteria in your WHERE clause or ON clause.
However, it looks strange to join customers on a condition on orders:
JOIN customers ON customers.customer_id = orders.customer_id AND orders.order_id = 3
This is not how an ON clause is supposed to work. So either:
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
WHERE orders.order_id = 3
or
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id
WHERE orders.order_id = 3
or
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id AND orders.order_id = 3
Many people prefer the last query over the second last, because you can easily convert the inner join into an outer join. So the general advice is: put criteria on the first table in WHERE and the criteria on other tables in ON. Make this a rule of thumb.
I my experience with SQL, when using an inner join (aka. join ), order of tables after the FROM clause has never made a difference in results. Also, it has not made any difference if I used a 'where' clause or an 'and' clause after the join. But this behavior is limited ONLY and ONLY to Inner joins. If you are using left or right joins, the order as well as Where/And clauses make a lot of difference in the results returned.
I'd like to add that if you have a lot of nulls in your keys(which should never be the case), that might affect the result set in inner joins when switching between Where and And or changing the sequence of tables after from.
I have to make it to show how many categories are available that are not currently any products in. Not sure what I am doing wrong, since I have moved stuff around and still get the result of 682 rows when there is supposed to be 0.
SELECT
Quantity,
ProductName,
CategoryID
FROM
Products,
OrderItems
WHERE NOT EXISTS (
SELECT Quantity
FROM OrderItems
WHERE Quantity IS NULL
)
Was told that "NOT EXIST" needs to be used in it.
You need a join condition between the tables. First hint: Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
I assume you want something like this:
SELECT oi.Quantity, p.ProductName, p.CategoryID
FROM Products p LEFT JOIN
OrderItems oi
ON oi.ProductId = p.ProductId
WHERE oi.quantity IS NULL;
The exact syntax is a bit of a guess, because you don't provide sample data.
I am not certain WHY but when I follow the example (from the northwind datase in a ms sql server) to do a subquery on Microsoft SQL Server Management Studio 2008 by typing in the code like shown below,
Select Orders.OrderID,
(Select Customers.CompanyName
From Customers
Where Customers.CustomerID = Orders.CustomerID) As Company Name
From Orders,
Customers
This sql code with subquery automatically gained a cross join and become
Select Orders.OrderID,
(Select Customers.CompanyName
From Customers
Where Customers.CustomerID = Orders.CustomerID) As Company Name
From Orders
CROSS JOIN Customers as Customers_1
I have played around with several variation of this but with no luck in eliminating this problem. Is this a known bug for microsoft sql server management studio 2008? If so, has it been patched, how do I find the patched? Otherwise, how can I report this to Microsoft and get them to really fixed it quickly?
In my actual query, I need to query/lookup the name of this particular table about 50 times by equating the ID and I think it is simply dumb having to do a JOIN of any sort for this because the code is crumpy, VERY long, and performance may be poor?
The subquery isn't causing the cross join, the lack of a condition controlling the join is. You need something like this:
Select Orders.OrderID, (Select Customers.CompanyName From Customers Where Customers.CustomerID = Orders.CustomerID) As Company Name
From Orders, Customers
Where Orders.CustomerID = Customers.CustomerID
I don't know why a sub-query is suggested by your book -- I would do it like this:
Select Orders.OrderID, Customers.CompanyName
From Orders
left join Customers on Customers.CustomerID = Orders.CustomerID
Looks like it should be a correlated-subquery
Select Orders.OrderID,
(Select Customers.CompanyName
From Customers
Where **Customers.CustomerID = Orders.CustomerID**) As Company Name
From Orders
--,
-- Customers
Why would you need Customers again when the inner Correlated Subquery brings the customer Name for each Order that is processed?
The Management Studio's insistence on adding CROSS JOIN is a warning that you are doing something strange. Trying to query two tables: Customer,Orders without any join condition.
Also, the query optimizer will usually convert these correlated sub-queries into joins during processing, but you can use the clearer syntax where appropriate.
Where is it appropriate? Particularly if you need to generate some sort of aggregate on the inner query.
It's nice to find such a useful site with genius members. I have been trying to find a solution for this SQLITE problem for a while now. Google didn't help me, except in finding this website. The SQL query works fine on the MSAccess version of the same database.
Here's my SQL statement - which didn't work for me.
SELECT Invoices.InvoiceNumber, Invoices.Quantity,Invoices.Code, Invoices.Price,Invoices.Discount, Invoices.InvoiceGrandTotal, Employees.EmployeeName, Customers.CustomerName, Invoices.DateOfInvoice, [price]*[Quantity] AS Total, Customers.Address, Products.Description,Products.Unit
FROM Products
INNER JOIN (
(
( Invoices INNER JOIN InvoiceDetails
ON Invoices.InvoiceNumber = InvoiceDetails.InvoiceNumber
) INNER JOIN Customers
ON Invoices.CustomerID = Customers.CustomerID
) INNER JOIN Employees
ON Invoices.UserID = Employees.EmployeeID
) ON Products.Code = InvoiceDetails.Code
WHERE (((InvoiceDetails.InvoiceNumber)='10111'));
The error message is: "Cannot compile Select-Statement: no such column: Invoices.InvoiceNumber"
That usually just means that you mis-spelled the column name ... check your Invoices table and make sure the column is InvoiceNumber and not "Invoice_Number" or something similar ...
Also, a much simpler version of this query would look something like this .. without all the strange nesting:
SELECT
Invoices.InvoiceNumber,
Invoices.Quantity,
Invoices.Code,
Invoices.Price,
Invoices.Discount,
Invoices.InvoiceGrandTotal,
Employees.EmployeeName,
Customers.CustomerName,
Invoices.DateOfInvoice,
[price]*[Quantity] AS Total,
Customers.Address,
Products.Description,
Products.Unit
FROM
Invoices
JOIN Employees
ON Employees.EmployeeID = Invoices.UserID
JOIN Customers
ON Customers.CustomerID = Invoices.CustomerID
JOIN InvoiceDetails
ON InvoiceDetails.InvoiceNumber = Invoices.InvoiceNumber
JOIN Products
ON Products.Code = InvoiceDetails.Code
WHERE
InvoiceDetails.InvoiceNumber = '10111'
I think the issue might be with case sensitivity. Unless I'm mistaken, MS Access field names are not case sensitive. Check the offending column name for the correct casing in you SQLITE table definition.