mySql query - web file sharing program - mysql

Here is my code. It is supposed to select the name of the person "to_whom" I'm sharing a particular file,
and the whole thing needs to return back the user_id (u_c.to_whom) and the user_name,
so I can populate my friends list with a checkboxe next to each other, that once clicked,
will share (save into a DB table) that particular file to a specific person.
This is from a web-app where users share files among each other.
SELECT u_c.to_whom, u.user_name
FROM files f
LEFT JOIN users_connections u_c
ON (u_c.who = :user_id OR u_c.to_whom = :user_id) AND u_c.friends = "Y"
LEFT JOIN users u
ON u.user_id = u_c.to_whom
WHERE f.file_id = 90
In the table files we have
file_id, file_name, file_desc, etc...
In the table users connections
id, who, to_whom, friends
1 1 4 Y
meaning that user 1 had initiated a friendship to user 4 and "Y" means the friendship is TRUE (N = still pending)
And in users we have
user_id, user_name
1 Jack
I cannot seem to get this working for some reason.
Can any advanced user help me out?
Thanks a bunch!!

I found the answer to this code. It is an essential code if you want to build a sharing file system.
$query_list_count = "SELECT COUNT(user_id)
FROM users_connections u_c
LEFT JOIN users u
ON u.user_id = u_c.who OR u.user_id = u_c.to_whom
LEFT JOIN files f
ON f.file_id = :file_id
WHERE (u_c.who = :user_id OR u_c.to_whom = :user_id AND friends = :friends)
GROUP BY u.user_id
";
$result_list_count = $db->prepare($query_list_count);
$result_list_count->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
$result_list_count->bindValue(':friends', "Y", PDO::PARAM_STR);
$result_list_count->bindValue(':file_id', $file_id, PDO::PARAM_INT);
$count_ = $result_list_count->fetchColumn();

Related

Using CASE for multiple conditions in MySQL query

Here's a MySQL query which I am using to get the roles for a user along with the comments.
But there are some cases where a user can be admin for multiple cases, in which case this query doesn't work.
This only shows up the first role of the user as an admin.
What would be the right way to use case for this situation?
select u.fullname, c.comment,
case when u.n_admin = 1 then 'n_admin'
when u.c_admin = 1 then 'c_admin'
when u.t_admin = 1 then 't_admin'
when u.i_admin = 1 then 'i admin'
end as role
from comments c
left join users u on u.id = c.user_id
where c.id= 34
As stated by #Matt-Spinks, your query is wrapping all the roles into one column.
Since, based on your query, user can have multiple independent admin roles (u.n_admin, u.c_admin etc), then you should report each column separately.
Since each only can be true or false, I would do it with IF() instead of CASE():
SELECT u.fullname, c.comment,
IF(u.n_admin = 1,'Yes','No') AS 'has n_admin role',
IF(u.c_admin = 1,'Yes','No') AS 'has c_admin role',
IF(u.t_admin = 1,'Yes','No') AS 'has t_admin role',
IF(u.i_admin = 1,'Yes','No') AS 'has i_admin role'
FROM comments c
LEFT JOIN users u on u.id = c.user_id
WHERE c.id= 34

How can I check the status of user x and user x?

I am looking for a SELECT query where I can find out the status of two users, status can be multiple things but let's keep it simple and check if both users are friends or not.
Using this query I can select every user that has x status, right now x means no status. But doing so I get the user table returned, I want the return to be true or false. Also, this query returns everyone that has x status with user x. I want to return true or false based on: if user x and x have a status, in this case friends. I hope I am not being to vague here.
SELECT
u.*
FROM User u
LEFT JOIN User_Status us
ON u.id = User_ID1
AND us.User_ID2 = 4
WHERE us.status IS NULL
User table:
ID-----first_name-----last_name-----etc...<br>**
-2--------James----------someting-------...<br>
-4----------Jack-----------someting-------...<br>
-5--------Sabrina---------someting-------...<br>
User_status table:
User_ID1-----User_ID2-----Status<br>**
-----------4-----------------2-----friends<br>
-----------2-----------------4-----friends<br>
-----------4-----------------5-----something else<br>
-----------5-----------------4-----something else<br>
Wanted result:
ID 2 (James) & ID 4 (Jack)
isFriend
true
ID 2 (James) & ID 5 (Sabrina)<br>
isFriend
false (They don't even have a status together.)
Indeed, your question is a little bit vague. Based on what I've understood, you want to find out if two users (known ID's) are friends or not?
The query below should help you with that.
SELECT
"A_USER_ID" as user_a,
"B_USER_ID" as user_b,
(
CASE
WHEN EXISTS(
SELECT *
FROM User_Status us
WHERE us.status = "friends" AND ((
us.User_ID1 = "A_USER_ID" AND us.User_ID2 = "B_USER_ID"
) OR (
us.User_ID1 = "B_USER_ID" AND us.User_ID2 = "A_USER_ID"
))
)
THEN "true"
ELSE "false"
END
) as friends
FROM
User u
WHERE
u.id = "A_USER_ID";

MYSQL, where if exists

I have 3 tables. User, alert and pref. User is obviously my user info table. Alert is my table where I store user alert/notification settings and pref is where I store my user preferences.
Not all users will have entries for prefs and alerts. When I'm trying to make a call for my alerts I'm running into trouble with my SQL knowledge.
I'm trying to do a 3 way join on user, alert and pref where the uid's are the same. I want to Select all user.id and ignore all uids that have an alert.deleted and pref.deleted = 1
user | alert | pref
id uid uid
alert_id pref_id
deleted deleted
One way to do that is
SELECT id
FROM user
WHERE user.id not in (SELECT uid FROM alert WHERE deleted = 1)
AND user.id not in (SELECT uid FROM pref WHERE deleted = 1);
But if you meant to say you want all users that actually have an alert and pref, just not the ones that are deleted, you could use
SELECT id
FROM user
INNER JOIN pref
ON user.id = pref.uid
AND pref.deleted = 0
INNER JOIN alert
ON user.id = alert.uid
AND alert.deleted = 0;
In your question you are talking about getting the alerts, so maybe there aren't any prefs necessarily for a particular user, but you do want all the not-yet-deleted alerts, then use
SELECT id
FROM user
LEFT OUTER JOIN pref
ON user.id = pref.uid
AND pref.deleted = 0
INNER JOIN alert
ON user.id = alert.uid
AND alert.deleted = 0;
Take your pick.
SELECT id
FROM user u
WHERE NOT EXISTS (SELECT 1 FROM alert WHERE uid = u.id AND deleted = 1)
AND NOT EXISTS (SELECT 1 FROM pref WHERE uid = u.id AND deleted = 1)
;

SQL Query complex tree join

I have a catalog that contains directories that can contain directories. The access of a directory can be granted to everyone or restricted to 0 to n user and/or to 0 to n usergroup. Access right is inherited in the hierarchy of group and from a group to its user. Therefore, a user can access a directory if he is allowed OR (he isn't deny AND (his group is allowed OR (his group isn't deny AND (his supergroup is allowed OR etc....
Their can be 1 to n level of groups, even if most of the time, their are typically no more than 3 levels.
I made a sqlfiddle from the schema : http://sqlfiddle.com/#!2/81b28
What I need is to get the list directories inside a given directory that can be accessible by a given user.
What I have so far is the following: this get the content of directory id '3' accessible to the user id '10', who is in usergroup '3' which is in supergroup '1' :
select l.id, l.accessright, ll.parentlibrarydirectoryid, ulc.*, glc1.*, glc2.*
from librarydirectory l
inner join a_librarydirectory_librarydirectory ll on ll.childlibrarydirectoryid = l.id
left join a_user_librarydirectory_canaccess ulc on ulc.librarydirectoryid = l.id
left join ws_user u on u.id = ulc.userid
left join a_group_librarydirectory_canaccess glc1 on glc1.librarydirectoryid = l.id
left join a_group_librarydirectory_canaccess glc2 on glc2.librarydirectoryid = l.id
where
ll.parentlibrarydirectoryid = 3
and (u.id = 10 or u.id is null)
and (glc1.groupid = 3 or glc1.groupid is null)
and (glc2.groupid = 1 or glc2.groupid is null)
and (l.accessright = "n"
or ((ulc.canaccess = "y")
or (ulc.canaccess is null and (glc1.allowedToAccess = 1
or (glc1.allowedToAccess is null and (glc2.allowedToAccess = 1))))));
It is working but I feel that this is not very elegant because I need to query the database to get the hierarchy of group prior to dynamically build the query in order to add as many a_group_librarydirectory_canaccess join and where clause as there are levels in the group hierarchy.
Is there a smarter way?
Thank you for your time

SQL: Series of joins

I am trying to find out how many comments there are in a question that has been made by the owner of the page (the admin).
tblQuestion: (question table)
queID
queUserID
queCompanyID (the owner of the page where questions are asked)
tblReplies: (where comments in the question are saved)
repQuestionID (queID = parent ID)
repUserID (the user ID who made the comment)
tblUsers: (where the users are stored)
uID (user ID, autoincrement)
uCompanyID (if this id is the same as a company id, the user is admin of that page)
So, I want to know how many reply posts are made by the company owner (a user with uCompanyID the reply posts' parent companyID - queCompanyID).
I tried doing this to get number of posts made by page admin, but does not seem to work:
SELECT COUNT(*) tblReplies.repID
FROM tblReplies
JOIN
tblQuestions ON tblQuestions.queID = tblReplies.repQuestionID
JOIN
tblUsers ON tblQuestions.queCompanyID = tblUsers.uCompanyID
WHERE tblQuestions.queID = 68 AND tblUsers.uCompanyID = 1
I really hope there is a ninja out there who can help me, I've spent hours and still nothing.
Thanks!
This should work (assuming there is a userID on the tblUsers table.:
SELECT
count(*),
tblReplies.repID
FROM
tblReplies,
tblQuestions,
tblUsers
WHERE
tblQuestions.queID = tblReplies.repQuestionID AND
tblQuestions.queCompanyID = tblUsers.uCompanyID AND
tblUser.uID = tblReplies.repUserID AND
tblUsers.uCompanyID = 1 AND
tblQuestions.queID = 68
GROUP BY tblReplies.repID
SELECT COUNT(*) AS total
FROM tblReplies
WHERE repQuestionID =68 AND repUserID =1
This should work.
SELECT count(*) as num_of_comments
FROM tblQuestion a
INNER JOIN tblReplies b
on a.queID = b.repQuestionID
INNER JOIN tblUsers c
on b.queCompanyID = c.uCompanyID
where a.queID = 68
and c.uCompanyID = 1