Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm looking at the example
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID;
from W3Schools and am wondering how I'm supposed to group the clauses in my mind. From what I understand, every SQL query returns a table, and clauses within the query may themselves return a table. So I think of the whole
Orders INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID
as being a table and I'm returning a sub-table of it by applying SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate to it. Is that the right way to think about things?
You can think of every query as if it composes a new temporary table with the result you want. This one takes rows from Orders and from Customers, matches them according to the CustomerID field in both tables (the on clause of the join), and then returns just several fields from Orders (OrderID and OrderDate) and one field from Customers (CustomerName).
Basically, you are returning a new table containing all of the columns in your SELECT statement. If you simplify the query to:
SELECT OrderID, OrderDate
FROM Orders
You'd get a printout of the entire Orders table, but with only the two columns you specified.
With your INNER JOIN, you are filtering out the results to only include the Orders that have a CustomerID that matches a similar row in the Customers table with that same CustomerID. And with your SELECT statement, you are adding a column that shows the customer's name that is matched up with those orders.
So the ON part of the INNER JOIN is just matching customers to their respective orders. The SELECT part is where you are creating the new output table with the three columns you are interested in.
Does that help?
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need some help with my exam, there are 2 questions but I don't know how to join them and which SQL statements I need.
Write a SQL statement which displays the employee id, last name,and salary of any employee whose salary is above the price of the most expensive product.
Write a SQL statement which displays the customer id of customers who purchased the product with product_id 1 but so far never purchased the product with product_id 3.
It would be nice if somebody explain me the solution.
With the understanding this is a practice exam, and that you don't have access to the tables/values....
You really should show what you've tried... but since you're new...
Question 1:
Return employeeID, last name and salary of all employees who have a salary greater than the price of the most expensive product (like how they avoided using the word max there...)
So this uses a subquery to get the max price from products and simply compares salary against it.
SELECT Employee_ID, Last_Name, Salary
FROM employees
WHERE salary > (Select max(price) from Products);
Question 2:
Generate two sets one for product_ID of 1 one for product_ID of 3 and make sure those with 1 are not in the group with 3.
and this uses a correlated subquery (notice how the PUR alias is in the subquery? that's why it's correlated)
So the first query gets all the customers buying product 1. The 2nd query finds all the customers buying product 3. and since we want only those customers who bought 1 not 3, we correlate the queries using not exists and we have our answer.
Exists - usually fastest as it can early exit the subquery once a single record for a customer is found.
SELECT Distinct PUR.Customer_ID
FROM purchases PUR
WHERE PRODUCT_ID = 1
and not exists (SELECT 1
FROM Purchases PUR2
WHERE Product_ID = 3
and PUR.Customer_ID = PUR2.Customer_I
There are 2-3 ways of doing this. I find the above the most efficient in most cases. However you could also do it by... a self join; or using an not IN statement
Self LEFT join (works great if you need data from multiple tables
We self join on purchases but filter each table instance to be for a specific product. we use left join as we want all records with product Id 1 and where a match is found in p2, we want to EXCLUDE those records so if the customer_ID is null that means they have no product 3 purchases
SELECT Distinct P1.customer_ID
FROM Purchases P1
LEFT JOIN Purchase P2
on P1.customer_Id = P2.customer_ID
and P2.Product_ID = 3
WHERE P1.Product_ID = 1
and P2.customer_ID is null
not in (usually slowest but works fine if subquery is for a VERY Small datasets)
SELECT Distinct PUR.Customer_ID
FROM purchases PUR
WHERE PRODUCT_ID = 1
and customer_ID not in (SELECT Customer_Id
FROM Purchases
WHERE Product_ID = 3)
Notice that neither of the 1st two answers uses a join; though a correlated subquery is close.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have been trying to figure this out for 4 days now. I am new to this and just can't this to work like it should. Any help would be appreciated.
*Not just looking for the answer
The president of the company wants a list of all orders ever taken. He wants to see the customer name, the last name of the employee who took the order, the shipper who shipped the order, the product that was ordered, the quantity that was ordered, and the date on which the order was placed. [Hint: You will need to join the following tables: Customers, Employees, Shippers, Orders, OrderDetails, Products, and to get all of the necessary information.]
Think about what you are trying to do here. You'll need to join together multiple tables to build the desired dataset. The type of JOINs you should be using will likely associate foreign keys from one table with the primary key of another. Please review JOINs if this is not clear.
Here is an example query that may get you on the right track. The column names used will likely vary, and I'll let you figure out how to get Quantity in the dataset (the quantity is probably in OrderDetails or perhaps you need to aggregate by product ID):
SELECT Customers.name, Employees.lastName, Shippers.name, Products.name,OrderDetails.orderDate
FROM Orders
JOIN OrderDetails ON OrderDetails.id = Orders.orderDetailId
JOIN Customers ON Customers.customerId = Orders.customerId
JOIN Employees ON Employees.employeeId = Orders.employeeId
JOIN Shippers ON Shippers.Id = OrderDetails.shipperId
JOIN Products ON OrderDetails.ProductId = Products.Id;
I should note that this is formatted for T-SQL and depending on your DBMS syntax may vary.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I'm having a hard time joining three separate tables in Oracle. I'm never joined three tables before so I'm not well versed. My theory is below:
SELECT customer_num WHEN customer_num IS 104 -198, order_num
FROM orders INNER JOIN items
ON order_num, stock_num
INNER JOIN stock
ON stock_num, description
Essentially, I'm trying to start with the ORDERS table and pull the customer number (customer_num) specifically customer number 104 -108 and the order_num from the orders table. Then attach the orders table to the Items table and attach the order_num and stock_num, and lastly attach the stock table and pull out the stock_num and description.
Your syntax is all over the place, and wouldn't work for a two-table join, or even querying a single table. Not sure where you got WHEN from, or the order of your clauses. Please review the SQL reference to see how to join and how to filter. Anyway...
You seem to want something like this:
SELECT o.customer_num, o.order_num, i.stock_num, s.description
FROM orders o
INNER JOIN items i ON i.order_num = o.order_num
INNER JOIN stock s ON s.stock_num = i.stock_num
WHERE o.customer_num BETWEEN 104 AND 198;
The WHERE clause is being applied to the orders table to restrict which customers' orders you get. I've assumed from your description that the orders and items tables have a common order_num column you can join on; and that the items and stock tables have a common stock_num column you can join on.
As OldProgrammer said, it would be helpful to include your table schemas in the question so assumptions don't need to be made, and showing sample data and expected output for that data would clarify what you're trying to do.
It should look something like this (based on the limited information about the schema)...
SELECT
O.CUSTOMER_NUM,
O.ORDER_NUM,
S.STOCK_NUM,
S.DESCRIPTION
FROM
ORDERS O,
ITEMS I,
STOCK S
WHERE
I.CUSTOMER_NUM >= 104
AND I.CUSTOMER_NUM <= 198
AND O.ORDER_NUM = I.ORDER_NUM
AND I.STOCK_NUM = S.STOCK_NUM
The syntax for a JOIN is:
TableExpression [ INNER ] JOIN TableExpression
{
ON booleanExpression | USING clause
}
The booleanExpression is what the tables will be linked by. So, in your example, something like this:
SELECT customer_num WHEN customer_num IS 104 -198, order_num
FROM orders INNER JOIN items
ON orders.<some_column> = items.<some_column>
INNER JOIN stock
ON items.<some_column> = stock.<some_column>
I am trying to understand the JOIN command from w3schools tutorial and there is an example.
Can you please "translate" it to me what exactly it does? I already know what do the dots do, but INNER JOIN, ON and so on messed me up?
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID;
And does it creates a new table in my SQL database or it just creates (lets call it..) "virtual" table which I can use it in the moment
The dot notation here signifies the column of a table.
Table.Column
So the SELECT is retrieving the columns specified from each table.
JOIN matches the tables based on the condition that appears after ON
this queries joins customers to orders based the condition of having the same CustomerID.
For more on joins check out http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
Perhaps the first thing to understand is the "dot notation." When you see a value like Orders.CustomerID SQL will read that to mean the CustomerID column within the Orders table.
The INNER JOIN is looking for an exact match for the records you specify with the ON clause...
So, in this example, SQL will first find all the records in the Orders table which have a CustomerID that matches the CustomerID found in the Customers table.
Then, it will look to the SELECT clause and show you the OrderID (from the Orders table), the CustomerName (from the Customers table) and the OrderDate from the Orders table.
If you're using SQL Server Management Studio (SSMS) or some other similar tool, it should display your results - kindof like a virtual table... but it doesn't actually create a table.
Hope that helps,
Russell
There are INNER AND OUTER JOINS. I think this post sums up those differences well.
What is the difference between "INNER JOIN" and "OUTER JOIN"?
As far as the concept itself you are 'joining' the tables by finding things in common between them based on a shared value in each. If you have ever done a vlookup with Microsoft Excel then you are familiar with this concept. In the query you've posted you are selecting values from both the Orders and Customers table. You can tell which table you are selecting values from by the prefix Orders. or Customers. You can then tell which column by the value following the dot i.e. OrderID, CustomerName, OrderDate.
The way the query knows to pull a conjoined field is if the CustomerID field matches.
So step by step
You are selecting
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
From the table Orders
FROM Orders
You wish to pull corresponding values from Customers. There are numerous join methods and logic that goes with each but you have chosen INNER JOIN explained in the link above.
INNER JOIN Customers
The criteria for joining is CustomerID
ON Orders.CustomerID=Customers.CustomerID;
To use an approximate Excel Vlookup analogy
The Lookup_value is CustomerID
The Table array is ORDERS
The range lookup is the type of join you are performing
SELECT statement returns data, it doesn't create any table not even virtual table whatsoever (if you see any table after executing SELECT statement, thats just a way the returned data presented). Create and modify table done using DDL (Data Definition Language) statements when SELECT is one of DML (Data Manipulation Language) [reference].
Join statement explained very well here, from basic use to more advance with illustration.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am trying to get the total cost of all the invoices for a customer. Ideally the end format will be two columns [customer name] and [total of invoices]. I have broken it down into the parts so far so I can check and better understand the process of joining the tables and have done a calculation to get the total of items on each invoice but now I am stuck.
As you can see from my screenshot ( Had to link to my google docs as I couldn't post the image up here - sorry) I am getting the company name listed multiple times. Once for each item and also for each invoice number and then item. How can I change my query to show the customer name only once with the corresponding totals of all the invoices combined?
I have lines 3 and 4 as comments of what I think is next so I can work this in steps before fine tuning the query to my desired output.
Thanks
Select Customer.CustName, Sum(InvoiceItem.Quantity*Item.ItemPrice) As TotalValue
From Customer
Inner Join Invoice On Customer.CustABN = Invoice.CustABN
Inner Join InvoiceItem On Invoice.InvoiceNo = InvoiceItem.InvoiceNo
Inner Join Item On InvoiceItem.ItemNo = Item.ItemNo
Group By Customer.CustName
Something like this should work using SUM and GROUP BY:
SELECT CustomerName, SUM(itemPrice * qty) InvoiceTotal
FROM YourTables With Your Joins
GROUP BY CustomerName
If you posted your entire query above, I could copy and paste into the example. But this should get you going in the right direction.
grouping could help, also you need to check if your dbms allows grouping without using agregate functions (some DBMS do not allw it, and return misleading results).
multiple companies is because of the relation company-invoice-product i guess.