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
Related
I have 2 MySQL tables A and B.
I would like to select only the records from B where a certain value exists in A.
Example:
A has columns: aID, Name
B has columns: bID, aID, Name
I just want the records from B for which aID exists in A.
Many thanks.
You need to do either INNER JOIN - records that exists in both tables, or use LEFT join, to show records that exists in A and matching IDs exists in B
A good reference:
You need to make a join, and if you don't want to retrieve anything from table b, just return values from table a.
This should work
select b.* from b join a on b.aID=a.aID
Below query will also work and will be effective
SELECT * FROM B
WHERE B.aID IN (SELECT DISTINCT aID FROM A)
You just need a simple inner join between tables A and B. Since they are related on the aID column, you can use that to join them together:
SELECT b.*
FROM tableB b
JOIN tableA a ON a.aID = b.aID;
This will only select rows in which the aID value from tableB exists in tableA. If there is no connection, the rows can't be included in the join.
While I recommend using a join, you can also replace it with a subquery, like this:
SELECT *
FROM tableB
WHERE aID NOT IN (SELECT aID FROM tableA)
You can use join like this.
Select b.col1,b.col2... From tableB b inner join table tableA a on b.field = a.field
Have you tried using a LEFT JOIN?
SELECT b.* FROM tableB b LEFT JOIN tableA a ON b.aID = a.aID
I need a little bit of help in creating this query. I'm joining TableA and TableB and getting a value out of it; then joining TableA and TableC and getting a value out if it. Finally I am substracting both values.
I'm not sure how to write this in a single query using a lot of JOIN or if I just do 2 subqueries and then substract them.
So far I have something like:
SELECT SUM(A.quantity) From TableA JOIN Table B WHERE ...
then
SELECT SUM(A.quantity) From TableA JOIN Table C WHERE ...
Given the chance that maybe TableA and TableB have no result, but TableA and TableC does, or viceversa, or maybe both have or maybe both won't, I can't just JOIN TableA and TableB and TableC
You can do this with a cross join:
select coalesce(s1.q1, 0) - coalesce(s2.q2, 0)
from (SELECT SUM(A.quantity) as q1 From TableA JOIN Table B WHERE ...) s1 cross join
(SELECT SUM(A.quantity) as q2 From TableA JOIN Table C WHERE ...) s2;
If one of the result sets returns NULL, the coalesce() treats the value as 0.
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.
I want to get row count in tableA if and only if rowA_x does not have a FK pointing to rowB_x in tableB.
tableA:
id | id_tableB
tableB
id | ...
So basically the rows in tableA should only be counted if the column id_tableA does not exist as id in tableB.
Is there a clean way to do such counting. I have around ~500.000 rows.
There are several (not 100% sure about the MySQL syntax, so this might require some tweaking):
Subselect with NOT IN:
select count(*) from tableA where id_tableB not in (select id from tableB);
Subselect with NOT EXISTS:
select * from tableA a
where NOT EXISTS (select null from tableB b where a.id_tableB = b.id);
OUTER JOIN:
select count(*) from (
select a.*, b.id as b_id
from tableA a
left join tableB b on a.id_tableB = b.id)
where b_id IS NULL;
Which of these is the fastest depends on your data, but usually, a JOIN is more efficient than a subquery.
Maybe you could use WHERE NOT EXISTS() structure.
If I understood well your question, your final query will look like:
SELECT COUNT(*)
FROM tableA
WHERE NOT EXISTS (SELECT id FROM tableB WHERE tableA.id = tableB.id_tableA)
The most efficient way I can think of doing this is using a sub-query:
SELECT COUNT(*)
FROM tableA
WHERE id_tableB NOT IN (
SELECT id
FROM tableB
)
;
Edit: However, upon further consideration, the below query may actually be more efficient as it uses a LEFT OUTER JOIN rather than a sub-query.
SELECT COUNT(*)
FROM tableA A
LEFT OUTER JOIN tableB B
ON A.id_tableB= B.id
WHERE B.id IS NULL
;
Updated
Hello all,
MySQL here.
Let's say we have 3 tables.
TableA, TableB, TableC.
TableB relates with foreign keys, TableA and TableC.
I would like to:
List some data from TableA and TableC BUT, that data should be ordered by some column of TableB.
Can I have an example of the above so that I can study it and try to transform to my needs?
Thanks a lot.
MEM
mysql allows you to order by colums that not selected, so you can join your tables
select ta.somefield, tc.somefield
from TableA ta INNER JOIN TableC tc on tc.somefield=ta.somefield
INNER JOIN TableB tb on tb.somefield=ta.somefield
ORDER by tb.somefield
SELECT TABLEA.fieldnames, TABLEC.fieldnames FROM TABLEA, TABLEB, TABLEC WHERE TABLEA.PRIMARY=TABLEB.TABLEA_PRIMARY AND TABLEC.PRIMARY=TABLEB.TABLEC_PRIMARY ORDER BY TABLEC.fieldname DESC
select
tA.blah,
tA.goop,
tC.schmarr,
tC.broigle
from
tB
join tA on tA.joincol1 = tB.joinCol1
join tC on tC.joinColx = tB.joinColx
order by
tc.schmarr