I am trying to retrieve the 'Roles' sets of a given users.id on a query with INNER JOIN combined with a WHERE condition. But things go wrong.
My database has four tables:
t_users : id, username, userpass, status, ...
t_action: id, id_user, id_role, id_type_role, ...
t_role: id, libelle, status
t_type_role: id, libelle, status
My query:
SELECT U.id AS ID, R.libelle AS ROLE, T.libelle AS TYPE
FROM t_user U
JOIN t_action A ON A.id_user = U.id
JOIN t_type_role T ON T.id = A.id_type_role
JOIN t_role R ON R.id = A.id_role
WHERE A.id_user = '1' AND R.libelle = 'System'
But this query returns no data. (Tested on a phpmyadmin SQL board.)
Use:
SELECT u.id AS id,
r.libelle AS role,
t.libelle AS type
FROM users u
JOIN action a ON a.id_user = u.id
JOIN type_role t ON t.id = a.id_type_role
JOIN role r ON r.id = a.id_role
WHERE a.id_user =1
AND t.libelle = 'System';
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=20570938deb2bec281d5070dd28bf19d
Don't put single quotes on integers, change WHERE a.id_user ='1' to WHERE a.id_user = 1.
libelle = 'System' is in the type_role table not in the role table
as Akina has already mentioned in the comment section, there is no "libelle" value in the table "role" which equals 'Système' as you has mentioned it above. That is the reason why you do not get any output. Fix it to 'System' in the MySQL database and try it out again.
Related
i have the table "user" (Primary key is id) and the table "user_meta" (Primary key is user_id and valid_from).
The user table contains basic user data e.g. username, password, etc.
The user_meta contains possible changing data e.g. lastname, gender(yea its 2018 :D) etc.
So i have a history on which day which data are valid.
My Problem ist that i try to select all user with the currently valid data, but i failed often...
How i can select the correct data ?
For one user i can simply use
"select * from user_meta
JOIN user on user_meta.user_id = user.id
ORDER BY valid_from DESC LIMIT 1"
but how its working with multiple/all users?
greetings,
False
you could use a join on a subselect for max_valid group by user
select * from user_meta
inner join (
select user.id, max(user_meta.valid_from) max_valid
from user_meta
JOIN user on user_meta.user_id = user.id
group by user.id
) t on t.id= user_meta.user_id and t.max_valid = user_meta.valid_from
or more simple
select * from user_meta
inner join (
select user_meta.user_id, max(user_meta.valid_from) max_valid
from user_meta
group by user_meta.user_id
) t on t.user_id= user_meta.user_id and t.max_valid = user_meta.valid_from
You probably want something along these lines:
SELECT u.*, um.*
FROM user u
INNER JOIN user_meta um
ON u.id = um.user_id
INNER JOIN
(
SELECT user_id, MAX(valid_from) AS max_valid_from
FROM user_meta
GROUP BY user_id
) t
ON um.user_id = t.user_id AND
um.valid_from = t.max_valid_from;
Not much to explain here, except that the subquery aliased as t will filter off all metadata records except for the latest one, for each user.
I'd like a query that shows me the tracks that a user doesn't have in his playlist. The only parameter I'll be getting is the username of a user.
Is that possible with this diagram? If so, could you provide me with a query?
I've tried a query, but not so succesfull.
SELECT * FROM TRACK
INNER JOIN USER u on u.ID = TRACK.USERID
INNER JOIN Playlist p on p.TrackID = TRACK.ID
WHERE (u.ID IN (SELECT UserID FROM Playlist WHERE UserID = (SELECT ID FROM User WHERE username = 'Arjan')))
AND (TRACK.ID NOT IN (SELECT ID FROM TRACK))
Not sure what's missing here. Maybe I'm just thinking too complicated.
I didn't get a chance to try it out actually. But your query should be something like this one --
Declare #UserName varchar(255)
Set #UserName = N'Arjun'
SELECT U.ID
,U.UserName
,P.ID
,T.Id
,T.TrackUrl
,T.CreationDate
FROM TRACK T
INNER JOIN USER U ON U.ID = T.UserID
LEFT JOIN Playlist P ON P.TrackID = T.ID
AND P.UserID = U.ID
WHERE U.ID IN (
SELECT DISTINCT ID
FROM User
WHERE UserName = #UserName
)
AND P.ID IS NULL;
I am working with a MySQL database. I am suppose to combine three select queries, to "improve performance". Each select below is dependent on the previous ID retrieved.
So far, I've tried the following...
# multiple select from tables
select user.name, group.ID
from user as u, group as g
where u.name = <name_here>
# inner join...
select user.ID, group.ID,
from user
inner join group
on user.ID = group.ID
I need to select the user.name and group.ID based on a username param. Is there a way to query this data in a single statement?
I don't know if I understand your need, lets try:
Try to use this query:
select pGroupMatch.GroupID, ProfileData.ID
from pUserMatch
inner join pGroupMatch on pGroupMatch.GroupID = pUserMatch.GroupID
inner join ProfileData on ProfileData.id = pGroupMatch.ProfileID
where pUserMatch.username = "<username>";
Check if you can create indexes for improve your query, if you can try it:
CREATE INDEX idx_pUserMatch_01 ON pUserMatch (GroupID);
CREATE INDEX idx_pGroupMatch_01 ON pGroupMatch (ProfileID);
Please use join for your requirement. Please try below query
select t3.* from Profiles.pUserMatch t1
left join Profiles.pGroupMatch t2 ON t2.GroupID=t1.GroupID
left join Profiles.ProfileData t3 ON t3.ID=t2.ProfileID
where t1.username = "<username>";
I hope above query will help you.Please feel free to comment. Thanks.
This is the query you get by joining the tree queries you already have:
SELECT pd.*
FROM Profiles.ProfileData pd
# ... where ID = "<profile_id>", profile_id = select ProfileID from ...
INNER JOIN Profiles.pGroupMatch pm ON pd.ID = pm.ProfileID
# ... where GroupID = "<group_id>", group_id = select GroupID from ...
INNER JOIN Profiles.pUserMatch pu ON pm.GroupID = pm.GroupID
WHERE pm.username = "<username>"
I put in comments the fragments of your queries that gets converted to JOIN subclauses.
Read more about the syntax of the JOIN subclause of the SELECT statement.
You don't need foreign keys to join stuff:
select p.* from Profiles.pUserMatch u
join Profile.pGroupMatch g on u.GroupID = g.GroupID
join Profile.ProfileData p on g.ProfileID = p.ID
where u.username = ?
I have a table of Users: id, type, name
and a table of Articles: id, writer_id, status
where articles.writer_id = users.id.
I'd like to display a table of each User's name WHERE type = 'writer' along with how many Articles are associated with them that have status = 'assigned'.
So far I have:
SELECT u.name, COUNT(a.id) as count
FROM users u LEFT OUTER JOIN articles a
ON a.writer_id = u.id
WHERE u.type = 'writer' AND a.status = 'assigned'
GROUP BY u.name
Problem is, this doesn't display writers with 0 'assigned'-status articles associated with them. I'm pretty sure I need a subquery but I'm not sure what to do. Thanks in advance!
Since you are using a LEFT JOIN, move the a.status = 'assigned' predicate from the WHERE clause to the JOIN clause.
SELECT u.name, COUNT(a.id) as count
FROM users u LEFT OUTER JOIN articles a
ON a.writer_id = u.id
AND a.status = 'assigned'
WHERE u.type = 'writer'
GROUP BY u.name
Explanation: For those users that do not have a article a.status will be NULL, Leaving the predicate in the WHERE defeats the purpose of a LEFT join, since NULL = 'assigned' will evaluate to false.
I know this is a simple syntax issue. Trying to delete all users from a subquery:
delete from users
where id IN (
select u.id
from users u
where not exists (select * from stickies i where i.user_id = u.id)
group by u.email
having count(*) > 1
)
Getting this error:
error : You can't specify target table 'users' for update in FROM clause
The subquery works fine (returns list of user id's).
DELETE u.*
FROM users u JOIN (
SELECT u.id
FROM users u LEFT JOIN stickies i ON i.user_id = u.id
WHERE i.user_id IS NULL
GROUP BY u.email
HAVING COUNT(*) > 1
) r ON r.id = r.id
Note: in the inner query, you are grouping by email, but selecting a user ID. this may return non deterministic results.