I am new to SQL Join topic. I don't know why my SQL Query is not working properly. Here is the query:
SELECT * from post
INNER JOIN user ON post.id = user.id
INNER JOIN follower ON user.id= follower.id
WHERE follower.fid = 20 OR user.id < 1000
ORDER BY pid DESC LIMIT 7
If I use this query it works:
SELECT * from post
INNER JOIN user ON post.id = user.id
WHERE user.id < 1000
ORDER BY pid DESC LIMIT 7
But adding another INNER JOIN gave no output.
Update :
I am using 2 INNER JOINS so that I can show data from 3 table if there are no followers in follower table then show data from 2 tables(post and user) only where id in user table is less then 1000.
Its because you probably have no follower on the post:
SELECT * from post
INNER JOIN user ON post.id = user.id
LEFT OUTER JOIN follower ON user.id= follower.id -- changed JOIN type
WHERE follower.fid = 20 OR user.id < 1000
ORDER BY pid DESC LIMIT 7
Remember INNER JOIN only returns if it finds the match in all JOIN conditions. Any condition will fail and you won't get the row.
For example:
You have a post, but the user has no follower. INNER JOIN will skip the row. Here comes the OUTER JOIN! it will give you the user row even when no follower is found.
Related
I want to improve my search performance. I want to search the user against the services and specialty. user in listed as per the filter applied either by specialty or by services or can be both.There are 5 tables i want to get the data from all the table
I have below table structure
1) users :- id ,first_name,last_name
2) users_services :- id ,user_id,service_id
3) users_speciality :- id,user_id,specility_id
4) mst_services :- id,name
5) mst_speciality :- id,name
I have used this query to get the result and it works fine.
select u.id,first_name,last_name,location,services.name as service_name,speciality.name as specility_name from users as u
inner join users_services on u.id =users_services.user_id
Inner join mst_services as services on services.id=users_services.service_id
inner join users_speciality on u.id =users_speciality.user_id
Inner join mst_speciality as speciality on speciality.id=users_speciality.service_id WHERE speciality.name ="specificity one"
as per the normalization it seems correct.But when data is more than 1,00,000 that time joining too many table causes may create problem.
what should i do for filter the user according to services and specialty ?
Have you tried like this ?
SELECT users.id,first_name,last_name, mst_services.name as service, mst_speciality.name AS speciality
FROM users
LEFT JOIN users_services ON users.id = users_services.user_id
LEFT JOIN users_speciality ON users.id = users_speciality.user_id
LEFT JOIN mst_services ON service_id = mst_services.id
LEFT JOIN mst_speciality ON speciality_id = mst_speciality.id
WHERE users.id IN
(SELECT user_id FROM users_services
WHERE service_id = (SELECT id FROM mst_services WHERE name = "service one")
UNION ALL
SELECT user_id FROM users_speciality
WHERE speciality_id = (SELECT id FROM mst_speciality WHERE name = "spercial one"))
ORDER BY first_name,last_name,service,speciality
I need to combine LEFT JOIN query with NOT IN query and have to get the result values from these queries. I have get the correct results while using these two queries at separately.
I have two tables likely user and answer
user table
user_id
1
2
3
4
5
answer table
user_id date
1 2015-10-15 21:23:14
2 2015-10-15 20:23:14
3 2015-11-11 16:23:14
LEFT JOIN query:
SELECT user.user_id
FROM user
LEFT JOIN answer
ON user.user_id = answer.user_id
WHERE DATEDIFF(NOW(),answer.date) > 5
This query returns result user_id 1,2.
NOT IN query:
SELECT user.user_id
FROM user
WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer)
This query returns result user_ids 4, 5.
I need to combine this two queries into single query so I tried with these two below queries:
SELECT user.user_id
FROM user
LEFT JOIN answer
ON user.user_id = answer.user_id
WHERE (DATEDIFF(NOW(),answer.date) > 5
AND user.user_id NOT IN (SELECT answer.user_id FROM answer))
and
SELECT user.user_id
FROM user
LEFT JOIN answer
ON user.user_id = answer.user_id
WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer)
AND DATEDIFF(NOW(),answer.date) > 5
But these return empty user_id.
Edit
Expected result should contain values of 1,2,4,5
If your meaning is about to combine 2 selection together Try Union All / Union :
SELECT * FROM
(
SELECT [WITH YOUR LEFT JOIN STATEMENT]
UNION
SELECT [WITH YOUR NOT IN STATEMENT]
) ResultTABLE
If you refer to the answer table in the WHERE clause, the answer.date will be restricted to non-NULL value, making the LEFT JOIN behave like a regular join. Move the condition to the ON condition to retrieve all the users, plus maybe the matching rows in answers:
SELECT user.user_id
FROM user u
LEFT JOIN answer a ON u.user_id = a.user_id
AND DATEDIFF(NOW(),a.date) < 5
;
Edit: after the edit of the question it appears the OP wants joined records with non existing answer OR answer.date too old/young:
SELECT user.user_id
FROM user u
LEFT JOIN answer a ON u.user_id = a.user_id
WHERE a.date IS NULL -- no answer record
OR DATEDIFF(NOW(),a.date) > 5 -- too old answer record
;
Final version: Since the OP wants to find users who don't have a (recent) answer, the query can be simplified to:
SELECT user.user_id
FROM user u
WHERE NOT EXISTS (
SELECT * FROM answer a
WHERE a.user_id = u.user_id
AND DATEDIFF(NOW(), a.date) <= 5
);
I'm using this query to get all the accounts with at least 3 projects.
SELECT
accounts.id,
accounts.name,
COUNT(accounts_project_1project_idb) as count
FROM accounts_project_1_c
LEFT JOIN accounts ON accounts_project_1accounts_ida = accounts.id
LEFT JOIN project ON accounts_project_1project_idb = project.id
LEFT JOIN project_cstm ON id_c = project.id
GROUP BY accounts_project_1accounts_ida
HAVING COUNT(accounts_project_1project_idb) >= 3
ORDER BY count DESC
Where accounts is the account table, project the project one, and project_cstm a table containing more information about projects
This request returns me 153 results.
But now, I would like to get the contact linked to an account. If it exists several contacts, I don't really care, I just want one.
SELECT
accounts.id,
accounts.name,
contacts.first_name,
contacts.last_name,
contacts.phone_mobile,
contacts.phone_work,
COUNT(accounts_project_1project_idb) as count
FROM accounts_project_1_c
LEFT JOIN accounts ON accounts_project_1accounts_ida = accounts.id
LEFT JOIN project ON accounts_project_1project_idb = project.id
LEFT JOIN project_cstm ON id_c = project.id
LEFT JOIN accounts_contacts ON accounts.id = accounts_contacts.account_id
LEFT JOIN contacts ON accounts_contacts.contact_id = contacts.id
GROUP BY accounts_project_1accounts_ida
HAVING COUNT(accounts_project_1project_idb) >= 3
ORDER BY count DESC
This request returns 173 results.
I don't really get it, using left join it should not add any row right?
Can you tell me what I'm doing wrong?
Thanks a lot.
I think you want the HAVING to be:
HAVING COUNT(DISTINCT accounts_project_1project_idb) >= 3
You probably want that in the SELECT as well.
I have following table in my database. I am trying to retrieve data from all three tables.
Table Structure:
User_New
User_ID
Name
Password
Email
User_Group_New
User_ID
Group_ID
Group_New
Group_ID
Group_Name
Issue: I am getting Duplicate records.
Query:
SELECT *
FROM `User_New`
INNER JOIN User_Group_New ON User_Group_New.User_ID = User_New.User_ID
INNER JOIN Group_New ON Group_New.Group_ID = User_Group_New.Group_ID
LIMIT 0, 30
SELECT DISTINCT *
FROM `User_New`
INNER JOIN User_Group_New ON User_Group_New.User_ID = User_New.User_ID
INNER JOIN Group_New ON Group_New.Group_ID = User_Group_New.Group_ID
LIMIT 0, 30
May that solve yours.
i have this 4 tables:
posts{id,post,date}
comment{id, user_id,post_id, comment, date}
tag_post{tag_id,post_id}
users{user_id, email,pwd,username}
i want to make this complex query, i want to get the maxiumum number of commenters(users) from a certain topic:
i.e.
select the most commeneters(count) on posts that have been tagged with tag_id=39
LIMIT 5
thanks :))
What about something like this :
select users.user_id, count(*) as nb_comments
from posts
inner join tag_posts on tag_posts.post_id = posts.id
inner join comment on comment.post_id = posts.id
inner join users on users.user_id = comment.user_id
where tag_posts.tag_id = 39
group by users.user_id
order by count(*) desc
limit 5
It should get you the five users who commented the most on posts that have the tag 39.