I have to write a query such that ,I need to get events whose start date is of 30 min from now.
My conditions are:
1) get the event from events table
2)Join created by of events with id in users table.
3)Comments from comment table with user ser id
But the problem here is if there is no comment for event then the event it self is not coming.If any comment is present it is coming.I dont want this.If comment is not there just fetch it as empty but not hide the total event .Can anyone please help me,.Thanks.
select u.email ,group_members.user_id,users.first_name,u.first_name
as host_name,events.name,events.start_date,comments.comments,c.first_name as
comment_user,comments.id from events
inner join users as u on u.id = events.created_by
inner join comments on events.id = comments.event_id
inner join group_members on events.group_id = group_members.group_id
inner join users as c on comments.from_user = c.id
inner join users on group_members.user_id = users.id
where events.start_date between date_add(now(),interval 1 minute) and date_add(
now(),interval 30 minute)
and group_members.user_status = 2
and events.status = 2
You need a left join to the comments table. I would put that table last in the from clause.
select u.email, gm.user_id, gu.first_name, u.first_name as host_name,
e.name, e.start_date, c.comments, uc.first_name as comment_user,
c.id
from events e inner join
users u
on u.id = e.created_by inner join
group_members gm
on e.events.group_id = gm.group_id inner join
users gu
on gm.user_id = gu.id left join
comments c
on e.id = c.event_id left join
users uc
on c.from_user = uc.id
where e.start_date between date_add(now(),interval 1 minute) and date_add(now(),interval 30 minute) and
gm.user_status = 2 and
e.status = 2;
Once you use a left join on comments, you also need a left join for the from user. I replaced all table names with aliases -- this makes it easier to track which table is used for which purpose.
Use the INNER JOIN Keyword and select the two columns by putting them with keyword ON.
SELECT EMP.EMP_ID, EMP.EMP_NAME, DEPT.DEPT_NAME FROM EMP
INNER JOIN DEPT ON DEPT.DEPT_ID = EMP.DEPT_ID;
Related
I have fours tables and I wanted to join all three tables with the one table.
I have listed my problem as follows:
Tables:
users
user_training
user_courses
user_certificates
I wanted to get the data from [2,3,4] tables that user_id field matches with the users table ID field.
When I try the INNER JOIN it gives me the result for users that are common in all the tables, But I just wanted to check the [2,3,4] tables with the table [1] Records.
My Query...
SELECT A.training_name AS 'training_name', C.course_name AS 'course_name', D.certificate_name AS 'certificate_name'
FROM user_training AS A INNER JOIN users AS B ON A.user_id=B.ID INNER JOIN user_courses AS C ON B.ID = C.user_id INNER JOIN user_certificates AS D ON B.ID = D.user_id;
Thanks in Advance.
use left join
select u.* from users u
left join user_training ut on ut.user_id=u.user_id
left join user_courses uc on uc.user_id=u.user_id
left join user_certificates uct on uct.user_id=u.user_id
With this one you are getting all users and their respective trainings:
SELECT *
FROM `users`
LEFT JOIN `user_training` ON `users`.`id` = `user_training`.`user_id`
Changing *_trainig to *_courses or *_certificates will return all users with respected courses or certificates.
If you need to get data in one query, try this one:
SELECT *
FROM `users`
LEFT JOIN `user_training` ON `users`.`id` = `user_training`.`user_id`
LEFT JOIN `user_courses` ON `users`.`id` = `user_courses`.`user_id`
LEFT JOIN `user_certificates` ON `users`.`id` = `user_certificates`.`user_id`
If user has no trainings, courses, certificates all remaining fields will be null-ed.
Let's say, I have 3 tables. "users", "topics" and "replies.
The "topics" and "replies" table do have a column "user_id" which references to "id" on the "users" table. The "replies" table also have a column "topic_id" which references "id" on "topics". Also imagine that each topic has 1 reply.
Now, I want to fetch all topics and resolve the username for both tables, so the output should include a "topic_username" and a "reply_username".
I know how to select the username for the topic, but how can I do that for both the topics and replies table?
Thanks
Updated code:
SELECT
t.*,
t_users.username as topic_user,
last_reply.user_id as last_reply_user_id,
r_users.username as last_reply_username,
last_reply.replies_count,
ORDER BY IFNULL(last_reply.created_at,t.created_at DESC
FROM
topics as t
left join users as t_users on t_users.id = t.user_id
left join ( select r.*,count(r.id) as replies_count from (select * from replies order by id desc) as r group by r.topic_id ) as last_reply on last_reply.topic_id = t.id
left join users as r_users on r_users.id = last_reply.user_id
Try this
SELECT
t.*,
t_users.name as topic_user,
r_users.name as reply_user
FROM
topics as t
left join replies as r on r.topic_id=t.id
left join users as t_users on t_users.id = t.user_id
left join users as r_users on r_users.id = r.user_id
this would work well if there is 1:1 topic and reply, if you have 1 to many replies then you are better off group by topic id and get the usernames by group concat
Version 2 (to get reply count and last reply user)
SELECT
t.*,
t_users.name as topic_user,
last_reply.user_id as last_reply_user_id,
r_users.name as last_reply_username,
last_reply.replies_count,
IFNULL(last_reply.created_at,t.created_at) as last_update
FROM
topics as t
left join users as t_users on t_users.id = t.user_id
left join ( select r.*,count(r.id) as replies_count from (select * from replies order by id desc) as r group by r.topic_id ) as last_reply on last_reply.topic_id = t.id
left join users as r_users on r_users.id = last_reply.user_id
ORDER BY IFNULL(last_reply.created_at,t.created_at) DESC
You wanna do this in a single query? You can do it like this but I believe a separate query for fetching replies and topics might be better (fetch replies first, get the unique topic IDs and then fetch topics in a separate query)
SELECT r.id, r.topic_id, ru.username AS reply_username, tu.username AS topic_username
FROM replies AS r
INNER JOIN topics AS t ON (t.id = r.topic_id)
INNER JOIN users AS ru ON (r.user_id = u.id)
INNER JOIN users AS tu ON (t.user_id = u.id)
i create a web app like facebook by php and mysqli
in my app i have a table for posts , one table for likes , and one table for comments
i want to get the number of comments and likes of each post in one row with his post_id!!!
i try some querys likes this :
select `tblpost`.`post_id`, COALESCE(TCOMM.`comment_num`,0) as `c_num`, COALESCE(TLIKE.`like_num`,0) as `l_num`
from
(select `tblpost`.`post_id`, count(*) as `like_num` from `tblpost` join `tbllikes` on `tbllikes`.`post_id` = `tblpost`.`post_id` group by `tblpost`.`post_id`
) TLIKE
inner join
(select `tblpost`.`post_id`, count(*) as `comment_num` from `tblpost` join `tblcomments` on `tblcomments`.`post_id` = `tblpost`.`post_id` group by `tblpost`.`post_id`) TCOMM
on
TCOMM.`post_id` = TLIKE.`post_id`
but i don't know what's my problem
You can do count distincts with two left joins.
Something like this would work if there are fields like_id and comment_id in the tables tbllikes and tblcomments
SELECT
tblpost.post_id AS post_id,
COUNT(DISTINCT tbllikes.like_id) AS likes,
COUNT(DiSTINCT tblcomments.comment_id) AS comments
FROM tblpost
LEFT JOIN tbllikes ON tbllikes.post_id = tblpost.post_id
LEFT JOIN tblcomments on tblcomments.post_id = tblpost.post_id
GROUP BY tblpost.post_id
First, I think you can greatly simplify your query:
select l.post_id,
COALESCE(c.comment_num, 0) as c_num, COALESCE(l.like_num, 0) as l_num
from (select l.post_id, count(*) as like_num
from tbllikes l
group by l.post_id
) l inner join
(select c.post_id, count(*) as comment_num
from tblcomments c
group by c.post_id
) c
on l.post_id = c.post_id;
This will only get you posts that have both likes and comments. To get what you want, use a left join:
select p.post_id,
COALESCE(c.comment_num, 0) as c_num, COALESCE(l.like_num, 0) as l_num
from tblpost p left join
(select l.post_id, count(*) as like_num
from tbllikes l
group by l.post_id
) l
on l.post_id = p.post_id left join
(select c.post_id, count(*) as comment_num
from tblcomments c
group by c.post_id
) c
on c.post_id = p.post_id;
This can't be too hard, but I don't know what the term is I'm looking for. I'm sure you guys can help me out. :)
I have a table tasks with rows that have a column project_id. Each project_id refers to (the id of) a row in the projects table. Each project belongs to a certain user which is why it has a column user_id.
I now want to select all tasks from this table where the project_id equals any project of a certain user.
Or put more simply:
Each TASK belongs to a PROJECT which belongs to a USER.
I want to create a SELECT-statement to receive all TASKS that belong to a specific USER. The only link between each TASK and a USER is through the PROJECT.
How do I accomplish this?
Thank you very much for your help! :)
JOIN the tables:
SELECT
t.*
FROM tasks t
INNER JOIN projects p ON t.project_id = p.project_id
INNER JOIN users u ON p.user_id = u.user_id
WHERE u.user_id = #AcertianUserId
SELECT
tasks.*
FROM
users
INNER JOIN
projects ON users.id = projects.user_id
INNER JOIN
tasks ON projects.id = tasks.project_id
WHERE
users.id = 1
SQL Fiddle
select t.*
from tasks t
join projects p on p.id = t.project_id
join users u on u.id = p.user_id
where u.id = 17
Try :
SELECT t.*
FROM user u, projet p, task t
WHERE u.id = p.user_id
AND p.id = t.project_id
AND u.id = your_id
Or (same result) :
SELECT t.*
FROM user u
INNER JOIN projet p ON u.id = p.user_id
INNER JOIN task t ON p.id = t.project_id
WHERE u.id = your_id
// Edit:
All work fine with:
SELECT u.*,
l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u
LEFT JOIN loans AS l
ON u.id = l.users_id
WHERE l.step < 12
OR NOT EXISTS
(SELECT l.id
FROM loans
WHERE l.users_id = u.id
)
GROUP BY u.id
Now, I can select all user, and his last loan. Thanks, and I think my solution will help future users.
if you want the last loan, you could append something like this
ORDER BY l.date DESC GROUP BY u.id
SELECT u.*,
l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u
LEFT JOIN loans AS l
ON u.id = l.users_id
WHERE u.id != :id
AND l.timestamp = (SELECT MAX(l.timestamp)
FROM loans AS l2
WHERE l2.users_id = l.users_id)
Where timestamp is a column on your table that indicates when the loan was created or otherwise gives you a time that you can compare to.
Try this:
SELECT u.*, l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u inner join
(
select max(l.loan_id) as loan_id, l.users_id , l.cod, l.step
from loans l
group by
l.users_id,l.cod,l.step
) as l
ON u.id = l.users_id
WHERE u.id != :id
Note: Avoid doing select * it's a very bad practice. List all the columns you need only.