SQL to query rows that do not have a value - sql

I am trying to query all rows of a "parts" table even if their number ordered is none. This is giving me a problem because when the number ordered is not on the "order_line" table it does not show the item as having none (which is essentially the reason for this question in the assignment)
Here is my sql for to find all of the parts with number ordered:
SELECT PART.PART_NUM,
PART.DESCRIPTION,
PART.ON_HAND,
PART.PRICE,
ORDERS.ORDER_NUM,
ORDER_LINE.NUM_ORDERED
FROM PART
INNER JOIN ORDER_LINE
ON PART.PART_NUM = ORDER_LINE.PART_NUM
INNER JOIN ORDERS
ON ORDER_LINE.ORDER_NUM = ORDERS.ORDER_NUM
ORDER BY PART.PART_NUM
This is for school so if you could just point me in the right direction that would be great. Hope this made sense..

use 'left outer join' in place of 'inner join' for the order_line table
EDIT: as pointed out by Martin, you need to replace both 'inner join's with 'left outer join'

As you can see, when you specify INNER JOIN it means that for a row to be in the result set it must be made up of an existing row from the left-hand side of the JOIN and an existing row from the right-hand side.
But INNER JOIN is not the only way to JOIN tables. You can also use LEFT or RIGHT OUTER JOIN, which requires only one of the two tables to have a row in it (the values that would have come from the other side of the JOIN are all NULL in the result set). There is even a FULL OUTER JOIN, which requires a row from either of the two sides.
Look up OUTER JOIN in your documentation for more information.

Related

SQL: JOIN vs LEFT OUTER JOIN?

I have multiple SQL queries that look similar where one uses JOIN and another LEFT OUTER JOIN. I played around with SQL and found that it the same results are returned. The codebase uses JOIN and LEFT OUTER JOIN interchangeably. While LEFT JOIN seems to be interchangeable with LEFT OUTER JOIN, I cannot I cannot seem to find any information about only JOIN. Is this good practice?
Ex Query1 using JOIN
SQL
SELECT
id,
name
FROM
u_users customers
JOIN
t_orders orders
ON orders.status=='PAYMENT PENDING'
Ex. Query2 using LEFT OUTER JOIN
SQL
SELECT
id,
name
FROM
u_users customers
LEFT OUTER JOIN
t_orders orders
ON orders.status=='PAYMENT PENDING'
As previously noted above:
JOIN is synonym of INNER JOIN. It's definitively different from all
types of OUTER JOIN
So the question is "When should I use an outer join?"
Here's a good article, with several great diagrams:
https://www.sqlshack.com/sql-outer-join-overview-and-examples/
The short answer your your question is:
Prefer JOIN (aka "INNER JOIN") to link two related tables. In practice, you'll use INNER JOIN most of the time.
INNER JOIN is the intersection of the two tables. It's represented by the "green" section in the middle of the Venn diagram above.
Use an "Outer Join" when you want the left, right or both outer regions.
In your example, the result set happens to be the same: the two expressions happen to be equivalent.
ALSO: be sure to familiarize yourself with "Show Plan" (or equivalent) for your RDBMS: https://www.sqlshack.com/execution-plans-in-sql-server/
'Hope that helps...
First the theory:
A join is a subset of the left join (all other things equal). Under some circumstances they are identical
The difference is that the left join will include all the tuples in the left hand side relation (even if they don't match the join predicate), while the join will only include the tuples of the left hand side that match the predicate.
For instance assume we have to relations R and S.
Say we have to do R JOIN S (and R LEFT JOIN S) on some predicate p
J = R JOIN S on (p)
Now, identify the tuples of R that are not in J.
Finally, add those tuples to J (padding any attribute in J not in R with null)
This result is the left join:
R LEFT JOIN S (p)
So when all the tuples of the left hand side of the relation are in the JOIN, this result will be identical to the Left Join.
back to you problem:
Your JOIN is very likely to include all the tuples from Users. So the query is the same if you use JOIN or LEFT JOIN.
The two are exactly equivalent, because the WHERE clause turns the LEFT JOIN into an INNER JOIN.
When filtering on all but the first table in a LEFT JOIN, the condition should usually be in the ON clause. Presumably, you also have a valid join condition, connecting the two tables:
SELEC id, name
FROM u_users u LEFT JOIN
t_orders o
ON o.user_id = u.user_id AND o.status = 'PAYMENT PENDING';
This version differs from the INNER JOIN version, because this version returns all users even those with no pending payments.
Both are the same, there is no difference here.
You need to use the ON clause when using Join. It can match any data between two tables when you don't use the ON clause.
This can cause performance issue as well as map unwanted data.
If you want to see the differences you can use "execution plans".
for example, I used the Microsoft AdventureWorks database for the example.
LEFT OUTER JOIN :
LEFT JOIN :
If you use the ON clause as you wrote, there is a possibility of looping.
Example "execution plans" is below.
You can access the correct mapping and data using the ON clause complement.
select
id,
name
from
u_users customers
left outer join
t_orders orders on customers.id = orders.userid
where orders.status=='payment pending'

Duplicates in Oracle Full Join [duplicate]

This question already has answers here:
What is the difference between "INNER JOIN" and "OUTER JOIN"?
(28 answers)
Closed 2 years ago.
I read this article about the working of Full Joins.
The article says that a Full Join, which combines the results of Left Join and Right Join, "retains duplicate rows". Therefore, in order to simulate a FULL JOIN, we use UNION ALL instead of UNION.
But, when I perform a FULL JOIN on two tables in Oracle, I do not find duplicates at all. (I believe, Oracle internally uses the 'UNION ALL' operation on left and right joins to perform a FULL JOIN.) The left join and right join contain some common rows, but when I run a full join, those common rows don't appear twice.
Results of Left Join :
SELECT * FROM ORDERS LEFT JOIN CUSTOMER ON ORDERS.CUSTOMERID = CUSTOMER.CUSTOMER_ID;
Results of Right Join :
SELECT * FROM ORDERS RIGHT JOIN CUSTOMER ON ORDERS.CUSTOMERID = CUSTOMER.CUSTOMER_ID;
Results of Full Join :
SELECT * FROM CUSTOMER FULL OUTER JOIN ORDERS ON CUSTOMER.CUSTOMER_ID = ORDERS.CUSTOMERID;
As you can see from the results of FULL JOIN, it "Does not contain duplicate rows" , even though left join and right join have some common rows.
So, why is it believed that a full join contains duplicate rows ? Am I missing something ?
I'm really a bit confused by what you mean by "duplicated rows". Joins don't generated "duplicates". What they do is include all combinations of rows with matching join keys.
In your case, customerid = 3 is repeated, so it would seem to be repeated in one or both tables. This is true in all your join queries.
If your data is properly structured, then orders.customerid should always match customers.customerid, unless the former is NULL. In a properly structured database, full join is very, very rarely needed. For instance, assuming that the customerid has a properly declared foreign key relationship, then you would want left join, with customers as the first table:
SELECT *
FROM CUSTOMERS c LEFT JOIN
ORDERS o
USING (CUSTOMERID);
With USING, CUSTOMERID only appears once in the result set.

about left outer join sql

So here's the scenario, I have two tables say payment and receipt with fields
payment_date, payment_amount, payment_party_code
and similarly
receipt_date, receipt_amount, receipt_party_code.
I have 4 rows in payment table, and 11 rows in receipt table.
What I want to do is select all rows from payment as well as from receipt table where the party_code is same. I did by using left outer join but failed because it is doing cartesian product of data.
Please help me out with this
Thanks
If you want ONLY the records that match on the payment_party_code, you should use an "INNER JOIN". But as marc_s said, you need to make sure that you specify your join criteria in your "ON" clause.
You need to use a LEFT OUTER JOIN and define a JOIN condition on it:
SELECT
p.payment_date, p.payment_amount, p.payment_party_code,
r.receipt_date, r.receipt_amount, r.receipt_party_code
FROM
dbo.Payment p
LEFT OUTER JOIN
dbo.Receipt r ON p.payment_party_code = r.receipt_party_code
This is for SQL Server (T-SQL). If you leave out the JOIN condition (the ON p.payment_party_code = r.receipt_party_code part), you'll get a cartesian product.
This will list all rows from the Payment table, and if they have info in the Receipt table, that'll be displayed as well.
If you want the opposite (everything from Receipt, even if there's no corresponding row in Payment for it), you need to either switch around the tables in the FROM ... LEFT OUTER JOIN (select from Receipt first), or you need to use a RIGHT OUTER JOIN so that you'll get everything from Receipt.
You might want to look at the Venn diagrams of SQL JOINs posted by Jeff Atwood - makes it quite clear what the different JOIN types really do...
Left Outer Join
The Left Outer Join logical operator returns each row that satisfies the join of the first (top) input with the second (bottom) input. It also returns any rows from the first input that had no matching rows in the second input. The nonmatching rows in the second input are returned as null values. If no join predicate exists in the Argument column, each row is a matching row
SELECT
pay.payment_date, pay.payment_amount, pay.payment_party_code,
rec.receipt_date, rec.receipt_amount, rec.receipt_party_code
FROM
payment pay
LEFT OUTER JOIN
receipt rec ON pay.payment_party_code = rec.receipt_party_code
select *
from party p
left outer join receipt r on p.party_code = r.party_code

SQL DB Question

Question about SQL View. Trying to develop a view from two tables. The two tables have same Primary Keys, execpt the 1st table has all of them, the 2nd has some, but not all. When I INNER Join them, I get a recordset but its not complete, because the 2nd table doesnt have all the records in it. Is there a way in my view to write logic stating that if the key isnt in there int he table #2 to insert a zero so the entire record set is shown in the view? I wan tto show ALL the records in the view even if theres nothing to inner join.
My example below:
SELECT dbo.Baan_view1b.Number, dbo.Baan_view1b.description, dbo.Baan_view1b.system, dbo.Baan_view1b.Analyst, dbo.Baan_view1b.[User],
dbo.Baan_view1b.[Date Submitted], dbo.Baan_view1b.category, dbo.Baan_view1b.stage, MAX(dbo.notes.percent_developed) AS Expr1
FROM dbo.Baan_view1b INNER JOIN
dbo.notes ON dbo.Baan_view1b.Number = dbo.notes.note_number
GROUP BY dbo.Baan_view1b.Number, dbo.Baan_view1b.description, dbo.Baan_view1b.system, dbo.Baan_view1b.Analyst, dbo.Baan_view1b.[User],
dbo.Baan_view1b.[Date Submitted], dbo.Baan_view1b.category, dbo.Baan_view1b.stage
HAVING (NOT (dbo.Baan_view1b.stage LIKE 'Closed'))
what you are looking for is the Left Join (left outer join) and not the inner join
SELECT dbo.Baan_view1b.Number, dbo.Baan_view1b.description, dbo.Baan_view1b.system, dbo.Baan_view1b.Analyst,
dbo.Baan_view1b.[User], dbo.Baan_view1b.[Date Submitted], dbo.Baan_view1b.category, dbo.Baan_view1b.stage,
MAX(dbo.notes.percent_developed) AS Expr1
FROM dbo.Baan_view1b
LEFT OUTER JOIN dbo.notes
ON dbo.Baan_view1b.Number = dbo.notes.note_number
WHERE NOT dbo.Baan_view1b.stage LIKE 'Closed'
GROUP BY dbo.Baan_view1b.Number, dbo.Baan_view1b.description, dbo.Baan_view1b.system, dbo.Baan_view1b.Analyst,
dbo.Baan_view1b.[User], dbo.Baan_view1b.[Date Submitted], dbo.Baan_view1b.category, dbo.Baan_view1b.stage
Also, changing the HAVING Clause to a WHERE clause makes the query more efficient.
Yes, you can do this. Assuming that baan_view1b has all the records and notes has only some, change
FROM dbo.Baan_view1b INNER JOIN dbo.notes
to say
FROM dbo.Baan_view1b LEFT OUTER JOIN dbo.notes
INNER JOIN (or just plain JOIN) tells the database engine to take records from Baan_view1b, match them up with records in notes, and include a row in the output for every pair of records that match. As you have seen, it excludes records from Baan_view1b that don't have matches in the notes table.
LEFT OUTER JOIN instead tells the engine to take ALL the records from Bann_view1b (because it's on the left side of the JOIN keywords). Then, it will match up records from notes wherever it can. However, you are guaranteed a row in the output for every row in the left-hand table regardless of whether it can be matched.
If, as is usual, you asked for column values from both tables, the columns from the table on the right-hand side of the JOIN will have NULL values in the missing rows.
Change the inner join to a left outer join.
(Or a right outer join or a full outer join if you feel fancy.)
You need a outer join. This shows all records that have a matching key as well as the ones that don't. The inner join only shows records that have matching join keys.
Enjoy!
You need to do a Left Outer Join as other posters have already mentioned. More information can be found here.

Compare inner join and outer join SQL statements

What is the difference between an inner join and outer join? What's the precise meaning of these two kinds of joins?
Check out Jeff Atwood's excellent:
A Visual Explanation of SQL Joins
Marc
Wikipedia has a nice long article on the topic [here](http://en.wikipedia.org/wiki/Join_(SQL))
But basically :
Inner joins return results where there are rows that satisfy the where clause in ALL tables
Outer joins return results where there are rows that satisfy the where clause in at least one of the tables
You use INNER JOIN to return all rows from both tables where there is a match. ie. in the resulting table all the rows and columns will have values.
In OUTER JOIN the resulting table may have empty columns. Outer join may be either LEFT or RIGHT
LEFT OUTER JOIN returns all the rows from the first table, even if there are no matches in the second table.
RIGHT OUTER JOIN returns all the rows from the second table, even if there are no matches in the first table.
INNER JOIN returns rows that exist in both tables
OUTER JOIN returns all rows that exist in either table
Inner join only returns a joined row if the record appears in both table.
Outer join depending on direction will show all records from one table, joined to the data from them joined table where a corresponding row exists
Using mathematical Set,
Inner Join is A ^ B;
Outer Join is A - B.
So it is (+) is your A side in the query.
Assume an example schema with customers and order:
INNER JOIN: Retrieves customers with orders only.
LEFT OUTER JOIN: Retrieves all customers with or without orders.
RIGHT OUTER JOIN: Retrieves all orders with or without matching customer records.
For a slightly more detailed infos, see Inner and Outer Join SQL Statements