using distinct rows for join mysql - mysql

Suppose I have table A, B
ID in A is unique but in table B, ID is not unique
I want to SELECT DISTINCT ID
query 1:
SELECT DISTINCT ID FROM A a LEFT JOIN B b ON a.ID = B.ID WHERE ...
query 2:
SELECT DISTINCT ID FROM A WHERE ID IN (SELECT DISTINCT ID FROM B where ...)
or
SELECT DISTINCT ID FROM A a LEFT JOIN (SELECT DISTINCT ID FROM B) b ON a.ID = B.ID WHERE ...
The end result is same but
what happens in query 1 is the space of temp table is more as multiple rows from table B will come with repeated ID
In query 2 i am able to optimize space and further processing as it will have limited rows with all distinct ID's
Isn't there any way to use DISTINCT rows from table B using join and avoiding subqueries?
Actually I have even table C which I will join with this, so I need to care for the number of rows taking part in 2nd join when taking join further with table C.

SELECT DISTINCT ID FROM A a LEFT JOIN (SELECT DISTINCT ID FROM B) b ON a.ID = B.ID WHERE ...
Is this what you want?
Edit so the answer is a bit more visible:
Since your A is unique, but B isn't you can just swap the values :
SELECT DISTINCT ID FROM B b LEFT JOIN A a on a.ID = b.ID WHERE...

Related

SQL Query to compare two tables for names

I am building a SQL query which compares two tables A and B by a [name] column and returns the names from table A that are not in table B
Example
Table A
ID Name Address
1 A ABC
2 B XYZ
3 C PQR
Table B
ID Name Gender
1 A F
2 B M
3 D F
The query I wrote should return third row from table A as it is not in table B and should exclude all other rows
Following is the query I built
Select * from A oa left join B gp ON oa.name!=gp.name
the above doesn't return the results I was expecting.
Can this be corrected?
Easiest way:
select * from A where name not in (select name from B)
Better way:
select * from A where not exists (select 1 from B where B.name = A.name)
"A left join B" means keeping everything in A, and associating records in B if the condition is satisfied.
In your case, if you really wanna use left join, here is what it should be ('=', not '!='):
Select * from A oa left join B gp ON oa.name=gp.name where gp.name is null
Better way would be using 'not exists' performance-wise, or 'except' if null values are not an issue.
Using excpet operator will help
select * from TableA
except
select * from TableB
SELECT a.*
FROM A a
LEFT JOIN B b
ON a.name = b.name
WHERE b.name IS NULL

Oracle Select Query based on Column value

I have two tables lets say
Table A
columns id , name address
Table B
columns id , age, import_date
The Table B id is a reference key of Table A.
Now I want to return results from A & B but if the record is not in B I still want to see the record so for this I use left outer join
Select * from A a left join B b
on a.id = b.id
Now even I don't have record in B I still get the record.
Table B may contain duplicate ids but unique import_date.
Now I want to results in a way that if there is duplicate id in table B then I want to get the records only where import_date is as of today.
I still want to get the records for ids which are not there but if the ID is there in table B then I want to apply above condition.
I hope someone can help me with this.
Sample data
Table A
01|John|London
02|Matt|Glasgow
03|Rodger|Paris
Table B
02|22|31-AUG-2015
02|21|30-AUG-2015
02|23|29-AUG-2015
The query will return
01|John|London|null|null|null
02|Matt|Glasgow|22|31-Aug-2015
03|Rodger|Paris|null|null
You almost got the solution. Just add one more condition like below
Select a.id,a.name,a.address,b.age,b.import_date
from tablea a left join tableb b
on a.id=b.id and b.import_date=trunc(sysdate)
order by a.id;---This line optional
Check the DEMO HERE
SELECT *
FROM Table_A t1 LEFT OUTER JOIN Table_B t2 ON t1.id=t2.id UNION
SELECT *
FROM Table_A t1 LEFT OUTER JOIN Table_B t2 ON t1.id=t2.id
GROUP BY t2.import_date
HAVING t2.import_date=CURDATE();

Get records not present in another table with a specific user id

I've this table (a)
And this table (b)
Now I have to get all records from A which are not present in B (a.id not present as b.idDomanda) and where B.idUser is not 1. So In this case, it should return only id 2 from a, but it returns 1 and 2.
This is my Query
SELECT a.* FROM a LEFT JOIN b ON a.id=b.idDomanda WHERE ( b.idUser <> 1 OR b.idUser IS NULL ) GROUP BY a.id
You want to move the condition on b to the on clause:
SELECT a.*
FROM a LEFT JOIN
b
ON a.id = b.idDomanda and b.idUser <> 1
WHERE b.idUser IS NULL
GROUP BY a.id;
The group by suggests that you might want to use not exists instead:
select a.*
from a
where not exists (select 1
from b
where a.id = b.idDomanda and b.idUser <> 1
);
There should be no results given your data set.
All records from A which are not present in B (a.id not present as b.idDomanda)
Given the test data set all of A is in fact IN b.idDomanda... even when filtering out userId = 1.
but as the previous person pointed out that is the query to check.

Select records from one table where a column value exists in another table

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

SQL - selecting userid which has max number of not null rows in a different table

I've 3 tables say A,B,C.
Table A has userid column.
Table B has caid column.
Table C has lisid and image columns.
one userid can have one or several caids.
one caid can have one or several lisids.
how do I select a userid which has maximum number of rows with image column as not null (in some lisids image column is blank and in some it has some value).
can someone please help.
Presumably, the ids are spread among the tables in a reasonable fashion. If so, the following should do this:
select b.userid, count(*)
from TableB b join
TableC c
on b.caid = c.caid
where c.image is not null
group by b.userid
order by count(*) desc
limit 1
The question in the comments is how you connect TableA to TableB and TableB to TableC. The reasonable approach is to have the userid in TableB and the caid in TableC.
Getting all the rows with the max requires a bit more work. Essentially, you have to join in the above query to get the list
select s.*
from (select b.userid, count(*) as cnt
from TableB b join
TableC c
on b.caid = c.caid
) s
(select count(*) as maxcnt
from TableB b join
TableC c
on b.caid = c.caid
group by b.userid
order by count(*) desc
limit 1
) smax
on s.cnt = smax.cnt
Other databses have a set of functions called window functions/ranking functions that make this sort of query much simpler. Alas, MySQL does not offer these.