MySQL table comparison between two tables - mysql

I have two tables, follow and followed. I want to get all the rows in the follow table such that follow.screen != followed.following_screen_name.
follow table
ID screen_name
-----------------
1 eddie
2 jason
3 omar
4 jonathan
5 jack
followed table
ID my_screen_name following_screen_name
-------------------------------------------
1 john eddie
2 kenny eddie
3 kenny omar
4 john jason
5 john omar
Query I tried which didn't work
SELECT follow.screen_name from follow, followed where followed.my_screen_name='john'
AND follow.screen_name != followed.following_screen_name
Expected results
ID screen_name
-----------------
1 jonathan
2 jack

you can get this by doing a LEFT JOIN
SELECT F.screen_name FROM follow F
LEFT JOIN followed FD
on F.screen_name = FD.my_screen_name
OR F.screen_name = FD.following_screen_name
WHERE FD.my_screen_name IS NULL
and FD.following_screen_name IS NULL
Another way is to use NOT EXISTS, get all rows that exists in followed and do NOT EXISTS clause to get desired result.
SELECT F.screen_name FROM follow F
WHERE NOT EXISTS
(
SELECT 1 FROM followed FD
WHERE F.screen_name = FD.my_screen_name
OR F.screen_name = FD.following_screen_name
)

There are plenty of ways to solve this, but common to all is that you need to compare the follow.screen_name to both followed.my_screen_name and followed.following_screen__name.
One way is to use NOT IN with a UNION:
select screen_name
from follow
where screen_name not in (
select following_screen_name
from followed
where following_screen_name is not null
union all
select my_screen_name
from followed
where my_screen_name is not null
)
While this approach is nice for clarity, it may not be as good for performance as using a left join or not exists.

A nice place to pick up mysql syntax and logic is here.
But try this code, it selects every row where the screen_name is not identical to anything produced in the next two queries:
SELECT * from follow WHERE screen_name
not in (select screen_name from followed)
AND not in (select followed_screen_name from followed);
The last two queries would look this and the WHERE filters all of the rows out with screen names identical to the fields below.
my_screen_name following_screen_name
-------------------------------------
john eddie
kenny eddie
kenny omar
john jason
john omar

Related

How to count a null value as 0 while using JOINS in Mysql database?

I have 2 tables as follows
Human
id name
1 John
2 mark
Computer
id human_id
1 2
2 null
I want my answer to be as following
name no_of_computer
John 0
mark 1
I tried the following but am wrong
select h.name,c.human_id) as 'no_of_computer' from human h
join
computer c on c.human_id = h.id
group by h.id
my code is not counting the null as 0 so its just avoiding that and only showing that mark has 1 computer, but I want to see John has 0 computer too. please help me out, thanks in advance
You can use a subquery that's something like:
SELECT
h.Name,
(SELECT COUNT(c.id_of_computers)
FROM computers c
WHERE c.id_human = h.id) as no_of_computer
FROM humans h
Do not cut and paste this to test, as I paid no attention to actual ID names in your tables. You'll have to look at that. 👍

Select and compare two columns from different tables to find matched records

I'm just learning PHP and MySQL and I have two tables in the same database : FirstYear , SecondYear that have a structure like this :
StudentId |Math | Physics StudentId1 | Math1 | physics1
Joe 10 14 Alan 12 17
Alan 13 17 Smith 11 13
Smith 9 9 Joe 10 15
Is it possible to write a query that select and compare the two columns StudentId , StudentId1 to find matched records and if for example Joe=Joe after that compare records of math with math1 and physics with physics1 that are in the same row as matched records of StudentId with StudentId1 ;the idea of this query is to study the improvement of same student from first year to the second one ,Thanks .
Yes, it is possible but you have to complete SQL fundamental course.
In this situation you have to know about JOIN. Such as, Inner Join, Left Join, Right Join, Full Join etc. Also, compare with unique id, not name. Because, name always duplicate. It is not good practice. So, Know about primary key and foreign key.
However,
Query-
SELECT * FROM FirstYear INNER JOIN SecondYear ON FirstYear.StudentId = SecondYear.StudentId1 WHERE FirstYear.id = 1
Something like that, alternatively, you can try to another logic.

Finding rows which match and blanks

I have a table of users and a table of electronic signatures - I want to be able to show for a given document who has signed and who has not.
Lets say we have employees:
EID Name
1 Bob
2 Tom
3 Fred
signatures:
EID Document Signature
1 1 Bob
1 2 Bob
1 3 Bob
2 1 Tom
3 2 Fred
My issue is that I can get this to work fine for document 4 - as no one has signed I can look where the document is null
However, if I look for document 2, for example, then I am currently getting employees missed off the list
For document 2 I would want to see
EID Signature
1 Bob
2
3 Fred
For document 4 I would want to see:
EID Signature
1
2
3
and for document 1:
EID Signature
1 Bob
2 Tom
3
The query I have tried to use is:
SELECT e.eid, s.signature
from employees e
left join signatures s on e.eid=s.eid
where s.document=? or s.document IS NULL group by e.eid
There are multiple issues:
Whenever using Left Join, any Where conditions on the right-side tables, should be put in the On clause. Otherwise, it will filter your result-set, even if there is no matching row (losing the purpose of Left Join)/
To compare null values, we use IS NULL. = null does not work. In this case, if we shift the conditions to On clause, we don't need to check for null values either.
Group By usage is invalid and really not required. When using Group By, only aggregated columns or the columns specified in Group By should come in Select. Refer: https://stackoverflow.com/a/41887524/2469308
Try the following:
SELECT e.eid, s.signature
FROM employees e
LEFT JOIN signatures s
ON e.eid=s.eid AND
s.document = ?

mySQL get row twice if field = this

I'm pulling a list of names from a mySQL table called users with the layout something like this;
id name anon
--------------------------------
1 Roger 0
2 Craig 1
3 LOL 0
For users where anon=1 I want to pull them twice, so the records I'd get from the above table would be 4 instead of 3:
1) Roger
2) Craig
3) Craig
4) LOL
I can imagine there's an easy way to do this but I'm getting brain block. Any suggestions?
Do a
Select name from users
union all
select name from users where anon = 1
and order them by name if desired?

Need to join 2 tables but except some rows in another table in MySQL

I'm not so expert. I need to join 2 tables but except a specific rows whose status is 'Del Edge'. And also duplicate rows are not allowed. I also try to write an query but I think it's not in correct form. For example user 't' log in and he search a name 'Bush', so I need only those data. Any help would be appreciated. Here are the example tables:
links Table:
Id(PK) source target freq
1 Bush Fisher 1
2 Lamburt Bush 6
3 Sam Bush 3
4 Fisher Sam 7
5 Bush Dalai 4
logs Table:
username Id (FK) source target frequency status
t 5 Bush Dalai 4 Add Node
m 8 Dalai Pit 5 Del Edge
t 3 Sam Bush 3 Del Edge
Joining Table should be:
source target frequency
Bush Fisher 1
Lamburt Bush 6
Bush Dalai 4
My Query:
"SELECT source, target, frequency from links, logs
where (links.source=Bush || links.target= Bush) &&
where not exists
(SELECT source, target, frequency FROM logs
WHERE (links.id = logs.id && logs.status=Del Edge)";
The following should do the trick!
SELECT DISTINCT k.source,
k.target,
k.frequency
FROM links k
LEFT JOIN logs g
ON g.id = k.id
WHERE IFNULL(status, '') != 'Del Edge'
AND 'Bush' IN( k.source, k.target )
Hope this helps!
Also, the following fiddle demonstrates that the above answer is, in fact, correct: http://sqlfiddle.com/#!2/9753f/5