Translate SQL query to absolute beginner (me) - sql

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.

Related

SQL refusing to do a join even when every identifier is valid? (ORA-00904)

Made this account just to ask about this question after being unable to find/expending the local resources I have, so I come to you all.
I'm trying to join two tables - ORDERS and CUSTOMER - as per a question on my assignment
For every order, list the order number and order date along with the customer number, last name, and first name of the customer who placed the order.
So I'm looking for the order number, date, customer number, and the full name of customers.
The code goes as such
SELECT ORDERS.ORDR_ORDER_NUMBER, ORDERS.ORDR_ORDER_DATE, ORDERS.ORDR_CUSTOMER_NUMBER, CUSTOMER.CUST_LAST, CUSTOMER.CUST_FIRST
FROM ORDERS, CUSTOMER
WHERE ORDERS.ORDR_CUSTOMER_NUMBER = CUSTOMER.CUST_CUSTOMER_NUMBER;
I've done this code without the table identifiers, putting quotation marks around ORDERS.ORDR_CUSTOMER_NUMBER, aliases for the two tables, and even putting a space after ORDR_ in both SELECT & WHERE for laughs and nothing's working. All of them keep coming up with the error in the title (ORA-00904), saying [ORDERS.]ORDR_CUSTOMER_NUMBER is the invalid identifier even though it shouldn't be.
Here also are the tables I'm working with, in case that context is needed for help.
Anyway, the query that produces the result you want should take the form:
select
o.ordr_order_number,
o.ordr_order_date,
c.cust_customer_number,
c.cust_last,
c.cust_first
from orders o
join customer c on c.cust_customer_number = o.ordr_customer_number
As you see the query becomes a lot easier to read and write if you use modern join syntax, and if you use table aliases (o and c).
You have to add JOIN or INNER JOIN to your query. Because the data comes from two different tables the WHERE clause will not select both.
FROM Orders INNER JOIN Customers ON Orders.order_Customer_Number = Customer.Cust_Customer_Number

SQL-92 Selecting with the dot operator

Before it is marked as a duplicate, I am not asking If I have to specify it fully, I am why it does not matter if it is specified. Hope that clears that up. Now to the question.
I'm new to SQL so I'm not sure if there is some technical term for this.
Say I have a database with tables: Orders and Customers.
Orders has categories: OrderID, CustomerID, and OrderDate
Customers has categories: CustomerID, CustomerName, ContactName, and Country
I then have a SQL Query:
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
So I am selecting Orders.OrderID, Customers.CustomerName, and Orders.OrderDate FROM Orders table. If it is from the Orders table, why specify Orders. before the OrderID and OrderDate in select ? This is an example from a website, and does not explain this. I am not sure if it has to do with join (which is in the example) so that's why I also put it there and in the tags.
-Thanks
Sometimes the column name is found in both tables and your DBMS will throw an error that the column is ambiguous. It's usually a good idea to explicitly declare which table you want the item to come from.
Using an alias often make the code easier to read and write:
SELECT ord.OrderID, cus.CustomerName, ord.OrderDate
FROM Orders ord
INNER JOIN Customers cus ON ord.CustomerID=cus.CustomerID;
These table names are pretty short, but you can see how useful aliases can be when the table names become longer and more complicated.
One benefit to explicitly declaring the table is that you can tell at a glance what table the data is coming from. Once you have data coming from many sources, through joins or not, it can be difficult to tell exactly which table a field is coming from, if you do not show the table in the select statements.

how can an unrelated table specified in FROM-clause affect the outcome of SUM()?

I am new to sqlite3 and have made some queries where the outcome seems strange to me. I have two tables, OrderDetails and Offices, that from their schema are unrelated. There are 7 entries in offices and 2996 in OrderDetails. Within OrderDetails, there is a column with quantityOrdered, and by summing the column values I get an accumulated value.
SELECT SUM(quantityOrdered) FROM OrderDetails; (result is 105516)
When I include the other table, which i don't actually extract any information from in my SELECT-clause and should be unrelated in attributes like so:
SELECT SUM(OD.quantityOrdered FROM OrderDetails OD, Offices; (result is 738612)
The result is much higher, and it is interesting to see that it is exactly 7 times larger (the number of entries in offices). I also get it even though I specify that it should only be OrderDetails attributes (OD.quantityOrdered). Is there some obvious logic that I don't see and understand? I hope someone can help me.
You are getting the sum for a CROSS JOIN since you dont have a JOIN condition.
Every row FROM the first table is JOINed to every other row from the other table.
Look here for a basic JOIN tutorial.
It should be
SELECT SUM(OD.quantityOrdered)
FROM OrderDetails OD JOIN Offices O
ON OD.somecol=O.someothercol
When you list two tables in a FROM clause but specify no conditions to relate them together, you get what is known as a CROSS JOIN, which calculates every possible combination of rows from the two tables.
You can see this by running
SELECT *
FROM OrderDetails, Offices
In more modern SQL that would be written
SELECT *
FROM OrderDetails
CROSS JOIN Offices
The SUM() function (without a GROUP BY) runs across all the rows in the result set, regardless of how the resultset was calculated (you can think of the SELECT clause running after the CROSS JOIN).
So your second query takes all the rows created by the CROSS JOIN and sums them up, meaning all the values are counted 7 times.
SELECT SUM(OD.quantityOrdered)
FROM OrderDetails as OD
CROSS JOIN Offices as O

SQL query with loop

I am having trouble with writing a SQL query in Access with foreign keys. There are two tables, 'Customers'(ID, Name, Surname) and 'Orders'(ID, Customer, Date, Volume). ID fields are primary, and Orders.Customer is a foreign key linked to Customers.ID, so a customer can have many orders or none.
My goal is to do a search on customers based on many criteria, one of which being if customers have at least an order which volume is superior to a certain quantity. I tried joins with SELECT DISTINCT but it still gives me duplicate results, plus I had to create an empty order for every customer without orders if the query didn't use the above condition.
Does anyone have an idea about that? Maybe some special instruction on foreign keys or 2 separate queries?
Based on the information you give, i only can give you hints on what I think you're doing/understanding wrong :
SELECT DISTINCT does select you a unique record, not a unique value, so if your statement selects all fields (*), distinct won't help you much there.
My guess is you had to create an empty order for each customer because you used INNER JOIN, try LEFT OUTER JOIN instead
For example :
SELECT DISTINCT Customers.*
FROM Customers
LEFT OUTER JOIN Orders
ON (Orders.Customer = Customers.id)
WHERE Volume > put_your_value

Why is my WHERE clause not return the CustomerIDs that are also in the Orders table?

My SQL statements are not returning any results. I am using the table that are on the www.w3schools.com web site. I want to have all of the customer IDS in my Customers table match all of the CustomerIDS in the Orders table. The SQL statement works that it goes through the table and checks every CustomerID to every Orders.CustomersID and when it finds a match doesn't it return that record.
Question: Why does the SQL not return the row when both customerIDS are equal because there are values that will return true?
SQL Statement:
SELECT * FROM Customers WHERE Customers.CustomersID = Orders.CustomersID;
One last thought: What is the best free SQL database that can be downloaded without a lot of hassle for home use?
Try this:
SELECT Customers.*
FROM Customers
JOIN Orders ON Customers.CustomerID = Orders.CustomerID;
If you just want customers that have orders then use:
SELECT *
FROM Customers
WHERE CustomerID IN
(SELECT CustomerID FROM Orders)
If you use a JOIN you may get multiple records per customer (if the customer has multiple orders). You can solve that with DISTINCT but IMHO a IN clause is cleaner (and likely faster)
You need a query like this: SELECT *
FROM Customers c
INNER JOIN Orders o on c.CustomerID = o.CustomerID;
w3schools is a very bad resource.
Selecting the best database is a bad question for stackoverflow. But the answer is PostgreSQL. (And lots of other DBMSs would fit the bill for you as well.)