Select multiple values from the same table - mysql

I have the following tables: joined_schedules, schedules, users
joined_schedules has: schedule_id, user_id, permission
schedules has: schedule_id, schedule_name
users has: user_id, name
permission can either be 0, 1, 2 (0 is an owner, 1 is an administrator and 2 is a regular user)
I am trying to select all of a users schedules where the permission is 2. I have no problem with this but I also need the owner of the schedule (permission = 0) in the same query. I am having trouble with this part.
The problem with this sql is that it only selects the schedule_id and the schedule_name. I also need the name of the user where their permission = 0 for the same schedule.
SELECT joined_schedules.schedule_id, schedules.schedule_name
FROM joined_schedules
INNER JOIN schedules
ON joined_schedules.schedule_id = schedules.schedule_id
WHERE joined_schedules.user_id = '$id'
AND joined_schedules.permission = 2
EDIT: I have also tried
SELECT joined_schedules.schedule_id, schedules.schedule_name, users.name
FROM joined_schedules
INNER JOIN schedules
ON joined_schedules.schedule_id = schedules.schedule_id
INNER JOIN users
ON users.user_id = joined_schedules.schedule_id
AND joined_schedules.permission = 0
WHERE joined_schedules.user_id = '$id'
AND joined_schedules.permission = 2

You can accomplish this by joining back on the joined_schedules table where permission = 0:
SELECT joined_schedules.schedule_id, schedules.schedule_name, u.name
FROM joined_schedules
INNER JOIN schedules
ON joined_schedules.schedule_id = schedules.schedule_id
AND joined_schedules.permission = 2
LEFT JOIN joined_schedules jsOwner
ON jsOwner.schedule_id = schedules.schedule_id
AND jsOwner.permission = 0
LEFT JOIN users u
ON u.user_id = jsOwner.user_id
WHERE joined_schedules.user_id = '$id'

Related

MYSQL Inner Join with IF Statement

I'm trying to join several tables in my database.
I need to get account information from the 'accounts' table with the latest meter history on it.
And if an account has no meter history, I want it to show 'meter' related fields as NULL.
Here's my query so far:
SELECT
accounts.id,
accounts.account_order,
acc.id AS accounts_class_id,
acc.zone,
acc.book,
acc.service_class,
acc.size,
acc.account_no AS series_no,
accounts.status,
application_address.address_line,
concessionaires.firstname,
concessionaires.middlename,
concessionaires.lastname,
mb.brand_name,
m.meter_no,
ms.meter_status
FROM
accounts
INNER JOIN
applications
ON accounts.application_id = applications.id
LEFT JOIN
application_address
ON applications.application_no = application_address.application_no
LEFT JOIN
concessionaires
ON applications.concessionaire_no = concessionaires.concessionaire_no
INNER JOIN
accounts_classifications acc
ON accounts.id = acc.account
INNER JOIN meter_history mh
ON mh.id = (SELECT id FROM meter_history mh2
WHERE mh2.account_id = accounts.id
ORDER BY mh2.status_date DESC
LIMIT 1)
LEFT JOIN
meter_status ms
ON mh.meter_status = ms.id
INNER JOIN
meter m
ON mh.meter = m.id
LEFT JOIN
meter_brand mb
ON m.meter_brand = mb.id
WHERE
acc.book = 1 AND acc.zone = 20 AND applications.status = '6' AND acc.status = '1'
This would return only accounts with meter history on it.
Where should I put my IF condition so I get accounts with no history as well, or if that is even possible with my query. Thank you!

How to select sql data by using 2 join tables with OR condition without duplicate records

I have a mysql select statement as below:-
select user.username, chat.from_user,chat.to_user,chat.message,chat.date_created
from chat join user on (chat.from_user or chat.to_user) in (user.user_id)
where(chat.from_user = 3 or chat.to_user = 3) and chat.chat_id IN
(SELECT distinct (MAX(chat.chat_id) )
FROM chat GROUP BY chat_group_id);
and here is my result
I always get username = admin. My expectation result is username will get correct from / to user.
Please help. Thank you.
SELECT
IF(chat.from_user=3, to_user
, IF(chat.to_user=3, form_user, 0)) AS username,
chat.from_user,chat.to_user,chat.message,chat.date_created
FROM chat
LEFT JOIN user fr_user ON chat.from_user = user.user_id
LEFT JOIN user to_user ON chat.to_user = user.user_id -- since you only want to show the TO_USERNAME, you can remove above line
WHERE (chat.from_user = 3 OR chat.to_user = 3) and chat.chat_id
IN
(SELECT distinct (MAX(chat.chat_id) )
FROM chat GROUP BY chat_group_id);
I think you intend:
select u.username, c.from_user, c.to_user, chat.message, c.date_created
from chat c join
user u
on u.user_id in (c.from_user, c.to_user)
where 3 in (c.from_user, c.to_user) and
c.chat_id in (select max(c2.chat_id)
from chat c2
group by chat_group_id
);

SQL query returns column with data from another column

I have a table Notices connected to tables Likes and Comments. When I return the notices for a user I also create columns: number_of_likes, number_of_comments and liked_by_me. The query is working correctly when the user making the query hasn't liked a notice (liked_by_me = 0) . But if they have (liked_by_me = 1) the value I get for number_of_likes is wrong and is the same as number_of_comments.
Example:
1)
- liked by me = false
- likes = 1
- comments = 5
Returned values:
- liked_by_me = 0
- number_of_likes = 1
- number_of_comments = 5
2)
- liked by me = true
- likes = 2
- comments = 5
Returned values:
- liked_by_me = 1
- number_of_likes = 5
- number_of_comments = 5
Here is the query I am using:
SELECT notices.*
, count(comment.id) as number_of_comments
, count(like1.user_id) as number_of_likes
, like2.user_id IS NOT NULL AS liked_by_me
, boards.name as board_name
FROM notices
LEFT JOIN comments as comment
ON (comment.notice_id = notices.id)
LEFT JOIN likes as like1
ON (like1.notice_id = notices.id)
LEFT JOIN likes as like2
ON (like2.notice_id = notices.id
AND like2.user_id = $1)
LEFT JOIN boards
ON (boards.id = notices.board_id)
LEFT OUTER JOIN board_users
ON (board_users.board_id = notices.board_id)
WHERE board_users.user_id = $1
GROUP BY notices.id
, boards.name
, like2.user_id
, userId
Any help would be appreciated. I have been on this for hours and I don't think I will be able to find the problem.
Thanks!
Solution:
Here is the working query
SELECT notices.*,
(SELECT COUNT(user_id) from likes WHERE likes.notice_id = notices.id) AS number_of_likes,
(SELECT user_id IS NOT NULL from likes WHERE likes.notice_id = notices.id AND likes.user_id = $1) AS liked_by_me,
count(comments.id) as number_of_comments, boards.name as board_name
FROM notices LEFT JOIN comments ON (comments.notice_id = notices.id)
LEFT JOIN boards ON (boards.id = notices.board_id)
LEFT OUTER JOIN board_users ON (board_users.board_id = notices.board_id)
WHERE board_users.user_id = $1 GROUP BY notices.id, boards.name", user);
You will have to use subeselects.
Excellent article on this problem: The GROUPing pitfall
TL;DR: Basically, you have to realize, that all your comments and likes are being multiplicated by one another. Try to display the result of the query without the group clause to see, that duplicate likes/comments are being counted.
EDIT: I didn't test this, but it's how the query might look:
(that is if user can only like one notice once, otherwise you would have to group current user likes too)
SELECT
notices.*,
comments.number_of_comments,
likes.number_of_likes
current_user_likes.user_id IS NOT NULL AS liked_by_me
boards.name AS board_name
FROM notices
LEFT JOIN (
SELECT
COUNT(*) AS number_of_comments,
notice_id
FROM comments
GROUP BY notice_id
) AS comments ON comments.notice_id = notices.id
LEFT JOIN (
SELECT
COUNT(*) AS number_of_likes,
notice_id
FROM likes
GROUP BY notice_id
) AS likes ON likes.notice_id = notices.id
LEFT JOIN likes AS current_user_likes
ON current_user_likes.notice_id = notices.id
AND current_user_likes.user_id = $1
LEFT JOIN boards ON boards.id = notices.board_id
INNER JOIN board_users
ON board_users.board_id = notices.board_id
AND board_users.user_id = $1;

3 Table MySQL JOIN Query?

This MYSQL Query gets the users from a SugarCRM Database
SELECT * FROM `users`
I use this MySQL query to get the Email address of a User from a SugarCRM database...
SELECT email_address FROM `email_addr_bean_rel`
LEFT JOIN `email_addresses` ON `email_addresses`.id = `email_addr_bean_rel`.email_address_id
WHERE `bean_id` LIKE '1'
AND `bean_module` LIKE 'Users'
AND `email_addresses`.deleted = 0
AND primary_address = 1
I need help building a SQL query to JOIN these as my goal is to build a User List of all users in a SugarCRM Database and have there primary email address be part of there user data.
IN the EMail SQL above the part WHEREbean_idLIKE '1' the number 1 is the User ID from the Users table.
The id column is what should be used to join the Users table to this email SQL.
Any help please?
SELECT users.*
,email_address
FROM users
LEFT JOIN email_addr_bean_rel
ON email_addr_bean_rel.bean_d=users.id
AND email_addr_bean_rel.bean_module = 'Users'
AND email_addr_bean_rel.primary_address = 1
AND email_addr_bean_rel.deleted = 0
LEFT JOIN email_addresses
ON email_addresses.id = email_addr_bean_rel.email_address_id
AND email_addresses.deleted = 0
try this
SELECT u.*, ea.email_address
FROM users AS u
INNER JOIN email_addr_bean_rel AS eab ON (eab.bean_id = u.id AND eab.bean_module = 'Users' AND eab.primary_address = 1)
INNER JOIN email_addresses AS ea ON (ea.id = eab.email_address_id AND ea.deleted = 0)
GROUP BY u.id

SQL query from multiple tables with multiple JOINs

I have the following database where user account details are stored in the Users table, organisation details are linked to users through the 'UsersOrganisation_Map' junction table and user permissions are linked to users through the UsersSiteRoles_Map junction table. The database is MySQL
What I'm struggling with is how to get data from both the roles and org tables in a single query and have the results returned as if they're from a single table.
Here's an example script (that doesn't work) that will hopefully describe what I'm trying to achieve.
> select * from UsersOrganisation_Map, UsersSiteRoles_Map join Users on
> UsersOrganisationMap.userID = Users.userID join Organisation on
> UsersOrganisationMap.organisationID = Organisation.organisationID
> where userEmail = 'admin#test.com' AND userPassword = 'test' AND
> accountActive = 'YES' join Users on UsersSiteRoles_Map.userID =
> Users.userID join SiteRoles on UsersSiteRoles_Map.roleID =
> SiteRoles.roleID
This should be something similar to:
SELECT
u.*,
usr.*,
sr.*,
uom.*,
o.*
FROM
Users as u
JOIN UsersSiteRoles_Map as usr
ON u.userID = usr.UserId
JOIN SiteRoles as sr
ON UsersSiteRoles_Map.roleID = sr.roleID
JOIN UsersOrganisation_Map as uom
ON u.userID = uom.userID
JOIN Organisation as o
ON o.organisationID = uom.Id
WHERE
u.userEmail = 'admin#test.com'
AND u.userPassword = 'test'
AND u.accountActive = 'YES'
You just need to join all the five tables together like :
SELECT *
FROM Users u
-- join to get roles
JOIN UsersSiteRoles_Map ur ON u.id=ur.user_id
JOIN SiteRoles r ON um.role_id=r.id
-- join to get organisation
JOIN UsersOrganisation_Map uo ON u.id=uo.user_id
JOIN Organisation o ON uo.organisation_id=o.id
-- filter results
WHERE u.email=admin ...