SQL outer join which omits common records - mysql

I'm trying to formulate an SQL FULL OUTER JOIN, which includes all values in table A and table B, but not those values common between them.
I have searched the internet, and stumbled upon the following SQL code:
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null
Which can be illustrated like so:
I'm not sure I understand the IS null parts. Could the SQL be carried out by simply stating something like the following as a WHERE condition? :
WHERE TableA.id <> TableB.id

What is it you don't understand about the IS NULL clauses?
In an OUTER JOIN (LEFT, RIGHT, FULL) there's a chance that columns from the outer table could end up as NULL.
The clauses
WHERE TableA.id IS null
OR TableB.id IS null
are simply saying that one of the IDs has to be NULL, I.E. if you have a row from TableA there can't exist a matching row from TableB and vice versa.

SELECT Name, ID FROM TableA UNION SELECT Name, ID FROM TableB
EXCEPT
SELECT Name, ID FROM TableB INTERSECT SELECT Name, ID FROM TableA
The first select gets all rows from table A and table B and combines this into 1 result set.
The second select selects all rows that are common between the two.
What the except does is select all rows from the first select - all rows from the second select.
What you end up with is all rows - the rows that are common between the two tables.

Related

MySql Join Issue When Join Two Tables

I have some doubt in MySQL joins
I have 2 tables for example TableA,TableB
TableA primary key is Foreign key of Table B
So I'm using inner join to get matched values but TableB have one column for row activate status so all active status is zero means I need to get that record or else I need to skip that record.
My query:.
Select * From TableA a inner join TableB b on a.id=b.aid where b.isActive=0;
The above query was return value if any one value is true
For example any one of is active row true. But I need to check all row is zero if it's all value zero means I need to return that so how I do that..?
Thanks in advance.
Select a.*
From TableA a
where not exists(SELECT 1 FROM TableB b WHERE a.id=b.aid AND b.isActive=1);
You can use your query change the filter as follows:
SELECT * FROM TableA a
JOIN TableB b ON a.id=b.aid
WHERE a.id NOT IN(SELECT aid FROM TableB WHERE isActive=1)

MySQL - Selecting rows where fields not equal

I have a little problem with an SQL query: I have 'TableA' with a field 'TableA.b' that contains an ID for 'TableB'. I want to select all rows from 'TableB' that don't have an ID that equals any field 'TableA.b'. With other words, I need every row from TableB that's not referred to by any row from TableA in field .
I tried a Query like this :
SELECT DISTINCT TableB.* FROM TableA, TableB Where TableA.b != TableB.ID
But the result contains a row that is also returned by the negation, i.e. where both fields have the same value.
Any ideas?
What you need is LEFT (or RIGHT) JOIN.
SELECT TableB.* FROM TableA
LEFT JOIN TableB on TableA.b = TableB.ID
WHERE TableA.b IS NULL
While it's possible to do the same with a subquery as in some of the otehr answers. A join will often be faster.
A LEFT [OUTER] JOIN can be faster than an equivalent subquery because
the server might be able to optimize it better—a fact that is not
specific to MySQL Server alone. Prior to SQL-92, outer joins did not
exist, so subqueries were the only way to do certain things. Today,
MySQL Server and many other modern database systems offer a wide range
of outer join types.
First, select all ids from TableA:
SELECT DISTINCT b FROM TableA
Then use that result to select all rows in TableB that have an id that does not exist in this set by using the above query as a subquery:
SELECT * FROM TableB WHERE ID NOT IN (SELECT DISTINCT b FROM TableA)
Hope this helps.
You can try this
SELECT TableB.* FROM TableB
WHERE ID NOT IN
(SELECT b from TableA);
Use NOT IN in SELECT Query.
SELECT * FROM TableB t1 WHERE t1.ID NOT IN (SELECT t2.b FROM TableA t2);
You can use right join also.
Try this:
SELECT DISTINCT TableB.* FROM tablea RIGHT JOIN TableB ON TableA.b = Tableb.ID WHERE TableA.B IS NULL

Condition on Left Join

I am trying the below queries where TABLE B is empty AND records in TABLEA
--This query fetched no records
SELECT TABLEA.COLA,TABLEA.COLB FROM TABLEA
LEFT JOIN TABLEB
ON TABLEA.ID=TABLEB.ID
WHERE TABLEB.COL1<>'XYZ'
--This query fetched records .
SELECT COL1 FROM
(
SELECT TABLEA.COLA,TABLEA.COLB FROM TABLEA
LEFT JOIN TABLEB
ON TABLEA.ID=TABLEB.ID
)A WHERE COL1 <>'XYZ'
Could you help me why first query didnt return any records though they look same. My understanding of first query is "I did a left join so if records doesnt exist in tableb, it should be replaced with NULL values. As NULL <>'xyz' all records should be fetched right..
Placing a WHERE condition on the OUTER joined table of an OUTER JOIN effectively renders that join as an INNER JOIN. So, if there are no rows in the outer table which satisfy the condition, then no rows will be returned.
The solution then is to include any such conditions within the join itself. In the example above this is as simple as changing WHERE to AND.
The one condition that must be placed in the WHERE clause is the test for NULL, the so-called exclusion join - I.e. when you actually want to return the inverse set.

MySQL left join, less results

I've got a little problem, I'm stuck with. I got two tables. The first one holds all id's, the second one some, but not all from tableA, a value and a corresponding identifier. As I thought I had it understood, a left join on the id's should give me all id's in the first table and null for the second, if the id doesn't exist in tableB. But I keep getting the number of id's that exist in both tables. Did I get the concept wrong?
My statement so far is:
SELECT tableA.id, tableB.desiredValue
FROM tableA
LEFT JOIN tableB ON tableA.id=tableB.item_id
WHERE tableB.element_id = 'something'
OR tableB.element_id IS NULL;
Any pointers?
Thanx, best regards,
Marcus
Move the condition that involves tableB column from WHERE to ON:
SELECT tableA.id, tableB.desiredValue
FROM tableA
LEFT JOIN tableB ON tableA.id=tableB.item_id
AND tableB.element_id = 'something'
--- WHERE tableB.element_id IS NULL --- this is probably not appropriate
;
Try this
SELECT tableA.id, tableB.desiredValue
FROM tableA
LEFT JOIN tableB ON tableA.id=tableB.item_id
AND (tableB.element_id = 'something'
OR tableB.element_id IS NULL);
In general, this seems like it should work. I'd be more specific in the where clause, however:
SELECT tableA.id, tableB.desiredValue
FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.item_id
WHERE tableB.element_id = 'something' OR tableB.item_id IS NULL;
I've substituted item_id as the row I'm checking for NULL in -- though it should make a difference unless element_id can be NULL in rows where the join works.
Can you expand on why you want the other portion of the where clause -- tableB.element_id = 'something' ? My general recommendation if you just want all rows returned would be to eliminate the WHERE clause entirely.
Can you explain a bit more what the criteria are for the rows you want returned in general?

Selecting from two tables, with different columns, where one needs a count

I have two tables, TableA and TableB.
I need to select one count value from TableA, based on a where condition.
I need to select two values from TableB.
I'd like all the values in one result set. There will never be more than one row in the result set.
Here's what I have now:
SELECT count(id) FROM TableA WHERE ($some_where_statement) SELECT owner, owner_ID from TableB
I know this should be simple, but this is throwing an error. Any suggestions?
You can cross join to join rows from two unrelated tables:
SELECT T1.cnt, T2.owner, T2.owner_ID
FROM (SELECT count(id) FROM TableA WHERE ($some_where_statement)) AS T1
CROSS JOIN (SELECT owner, owner_ID from TableB) AS T2
To have only one row in the result set, it is assumed that both subqueries only return one row. I suspect that this is not the case for the second subquery. You are probably missing a where clause.