I have three tables, user/team/user_team(many-to-many)
user
-----------
id name
1 Tom
2 Jerry
3 John
team
------------
id name
1 t1
2 t2
3 t3
user_team
---------------------
userid teamid isdeleted
1 t1 0 <----(0 means not deleted record, which can be searched out)
2 t2 1 <----(1 means deleted record, which can not be searched out)
I want to get all team records information with associated user information like below
--------------
tid tname username
1 t1 Tom
2 t2
3 t3
Can you tell me how to write the sql statement?
Sorry for my mistake. I've updated my question by adding one more record t3 in team table.
try this:
Select a.id as tid
a.name as tname
b.name as username
from team a
LEFT JOIN user_team c on a.name = c.teamid and c.isdeleted = 0
LEFT JOIN user b on b.id = c.userid
I think what you're looking for is a simple OUTER JOIN:
select t.id as tid,
t.name as tname,
u.name as username
from team t
left join user_team ut on t.id = ut.teamid and ut.isdeleted = 0
left join user u on ut.userid = u.id
A Visual Explanation of SQL Joins
Try this:
SELECT t.id tid, t.name tname, GROUP_CONCAT(u.name) usernames
FROM user_team ut
LEFT OUTER JOIN team t ON ut.teamid = t.id
LEFT OUTER JOIN user u ON ut.userid = u.id
GROUP BY t.id;
To include the flag that can be searched out try this (just include a condition for flag):
SELECT t.id tid, t.name tname, GROUP_CONCAT(u.name) usernames
FROM user_team ut
LEFT OUTER JOIN team t ON ut.teamid = t.id
LEFT OUTER JOIN user u ON ut.userid = u.id
AND ut.isdeleted = 1 --this will add a condition for deleted teams
GROUP BY t.id;
Give it a try. See a demo fiddle here http://sqlfiddle.com/#!2/d918a/2
select t.id as tid,
t.name as tname,
case when ut.isdeleted = 0 then u.name else '' end as username
from team t
left join user_team ut
on t.name = ut.teamid
left join user u
on ut.userid = u.id;
Which will result in
Related
I have three tables, users(which includes user details), territory_categories(which has different territory names and their ids), user_territory(a junction table between the two)
I want to filter users based on selected territory from the list.
query for that is --
SELECT u.id,account_id_fk,first_name,last_name,email_address,password,mobile_number,gender,user_accuracy,check_in_radius,report_to,role,allow_timeout,
active,last_logged_on,last_known_location_time,last_known_location,u.created_on,u.created_by,
(SELECT COUNT(DISTINCT u2.id) FROM fieldsense.users u2
INNER JOIN user_territory t1 ON u2.id=t1.user_id_fk
INNER JOIN territory_categories c on c.id=t1.teritory_id
**WHERE c.category_name LIKE** "Gujarat" AND(u2.account_id_fk=1 AND u2.role!=0) ) AS usersCount,
IFNULL(a.id,0) attendanceId,IFNULL(a.punch_date,'1111-11-11') punchInDate,IFNULL(a.punch_in,0) punchIntime,IFNULL(a.punch_out_date,'1111-11-11') punchOutDate, IFNULL(a.punch_out,0) punchOutTime
FROM fieldsense.users as u
LEFT OUTER JOIN attendances as a ON u.id=a.user_id_fk AND a.id=(select max(id) from attendances att where att.user_id_fk=u.id)
INNER JOIN user_territory t1 ON u.id=t1.user_id_fk
INNER JOIN territory_categories c on c.id=t1.teritory_id
**WHERE c.category_name LIKE "Gujarat"**
GROUP BY u.id **limit 10**
OUTPUT :
usersCount: 136
attendanceId: 0
punchInDate: 1111-11-11
punchIntime: 0
punchOutDate: 1111-11-11
punchOutTime: 0
10 rows in set (2.06 sec)
And without where clause when it loads it takes almost 1 minute to display the data
OUTPUT without where clause :
usersCount: 144
attendanceId: 0
punchInDate: 1111-11-11
punchIntime: 0
punchOutDate: 1111-11-11
punchOutTime: 0
10 rows in set (54.45 sec)
I am getting the desired output, but query is taking almost 1 minute to load, which i want to optimize. how can i do this ?
Try this out. I just narrowed down your inner join on table user_territory, so it will not join whole user_territory table but will only join distinct user_ids in it. Hope it reduces the performance time,
SELECT u.id,
account_id_fk,
first_name,
last_name,
email_address,
PASSWORD,
mobile_number,
gender,
user_accuracy,
check_in_radius,
report_to,
role,
allow_timeout,
active,
last_logged_on,
last_known_location_time,
last_known_location,
u.created_on,
u.created_by,
(
SELECT
COUNT(u2.id)
FROM
fieldsense.users u2
INNER JOIN (SELECT DISTINCT user_id_fk as id, territory_id FROM user_territory ) t1 ON u2.id = t1.id
INNER JOIN territory_categories c ON c.id = t1.teritory_id
WHERE
c.category_name LIKE "Gujarat"
AND (
u2.account_id_fk = 1
AND u2.role != 0
)
) AS usersCount,
IFNULL(a.id, 0) attendanceId,
IFNULL(a.punch_date, '1111-11-11') punchInDate,
IFNULL(a.punch_in, 0) punchIntime,
IFNULL(
a.punch_out_date,
'1111-11-11'
) punchOutDate,
IFNULL(a.punch_out, 0) punchOutTime
FROM
fieldsense.users AS u
LEFT OUTER JOIN attendances AS a ON u.id = a.user_id_fk
AND a.id = (
SELECT
max(id)
FROM
attendances att
WHERE
att.user_id_fk = u.id
)
INNER JOIN (SELECT DISTINCT user_id_fk as id, territory_id FROM user_territory ) t1 ON u2.id = t1.id
INNER JOIN territory_categories c ON c.id = t1.teritory_id
WHERE
c.category_name LIKE "Gujarat"
GROUP BY
u.id
LIMIT 10
Just like the title suggest, I'm having a problem excluding duplicate values from 2 united queries.
My query looks a little complicated so I will try to simplify it by another example:
SELECT u.name
FROM user u
LEFT JOIN user_hobby uh on uh.user_id = u.id
JOIN teams t on t.id = u.team
JOIN group g on g.id = uh.group and g.name = 'average'
where u.active = 1 and u.team is not null
UNION
SELECT u.name
FROM user u
LEFT JOIN user_hobby uh on uh.user_id = u.id
JOIN teams t on t.id = u.team
where u.active = 1 and u.team is null
so basically, both queries gave me the correct answers but with duplicate values
first query output:
ben, miche, anna, robert
second query output:
jean, charles, anna, robert
How do I use UNION in both query where I can omit anna and robert if it already appeared in the first query?
UNION already removes the duplicate entries.
(
SELECT u.name
FROM user u
LEFT JOIN user_hobby uh on uh.user_id = u.id
JOIN teams t on t.id = u.team
JOIN group g on g.id = uh.group and g.name = 'average'
where u.active = 1 and u.team is not null
)
UNION
(
SELECT u.name
FROM user u
LEFT JOIN user_hobby uh on uh.user_id = u.id
JOIN teams t on t.id = u.team
where u.active = 1 and u.team is null
)
Have you tried using Distinct in SELECT ?
Try - Select distinct x.name from ( query 1 UNION query 2 ) x
I have 3 tables: tickets, tickets_users and users. My problem is that in the users table I have 2 types of users: requesters and solvers: type 1 and 2.
I want to select the ticket, requester (if any, can be multiple) and solver (if any, can be multiple).
I'm thinking something in the lines of:
SELECT
t.id, t.description,
(u.id where u.type = 1) AS requester,
(u.id where u.type = 2) AS solver
FROM
tickets t
INNER JOIN
tickets_users tu ON t.id = tu.ticket_id
INNER JOIN
users u ON tu.user_id = u.id
Obviously this does not work.
The tables look like this:
Tickets:
ID Description
1 Description 1
2 Description 2
Tickets_users
ID Ticket_ID User_id Type
1 3 4 1
2 5 8 2
Users
ID Name
1 John
2 Mary
Thanks,
In the meantime I think I found a solution using a sub-query in the join clause, but to me it looks rudimentary:
SELECT
t.id, t.name AS ticket_name, type1.users_id AS requester,
type2.users_id AS solver
FROM
tickets t
INNER JOIN
(SELECT users_id, tickets_id
FROM tickets_users
WHERE TYPE = 1) type1 ON t.id = type1.tickets_id
INNER JOIN
(SELECT users_id, tickets_id
FROM tickets_users
WHERE TYPE = 2) type2 ON t.id = type2.tickets_id
Should be something like this.
SELECT
t.id, t.description, u.id, userType
CASE WHEN u.type = 1 THEN 'requester' ELSE 'solver' END
FROM
tickets t
INNER JOIN tickets_users tu ON t.id = tu.ticket_id
INNER JOIN users u ON tu.user_id = u.id
Please provide sqlfiddle in case above example does not work.
With Joins,
SELECT
t.id, t.description, requesters.id, solvers.id
FROM
tickets t
INNER JOIN tickets_users tu ON t.id = tu.ticket_id
LEFT JOIN users requesters ON (tu.user_id = requesters.id AND requesters.type=1)
LEFT JOIN users solvers ON (tu.user_id = solvers.id AND solvers.type=2)
As you can tell, users table is joined twice (as requesters and as solvers with additional conditions). The reason LEFT JOIN is used is because if there's a record with no requesters or no solvers, INNER JOIN would completely ignore the whole record until it has a requester and a solver.
I'm trying to get names of users from a voting table, I can't quite figure out how to get both the voter's name and the votee's name.
Simplified Votes Table
ID voteeID voterID
1 1 2
2 1 3
3 1 4
4 2 1
5 2 3
6 2 4
Simplified User Info Table
ID username
1 Bob
2 Sam
3 Ed
4 Mark
Where I'm at:
SELECT votes.voteeID, votes.voterID, userinfo.username
FROM votes
JOIN ???
I was playing around with the join, but I'm kind of stuck. If I join on the votee's id to the userinfo id, how would I also get the voter's name or vice versa?
Database: MySQL 5
Any help or even a hint would be wonderful, thanks in advance.
try this one,
SELECT b.`username` as Votee_Name,
c.`username` as Voter_Name
FROM Votes a
INNER JOIN UserInfo b
ON a.voteeID = b.Id
INNER JOIN UserInfo c
on a.voterID = c.id
SQLFiddle Demo
How about something like
SELECT v.ID,
v.voteeID,
u1.username Votee,
v.voterID,
u2.username Voter
FROM Votes v INNER JOIN
User u1 ON v.voteeID = u1.ID INNER JOIN
User u2 ON v.voterID = u2.ID
You need to take INNER JOIN twice to get usernames for both votee and voter:
SELECT a.voteeID, a.voterID,
b.username AS votee_name, c.username AS voter_name
FROM votes a
INNER JOIN userinfo b
ON a.voteeID = b.ID
INNER JOIN userinfo c
ON a.voterID = c.ID;
SELECT V.ID as ID B.username as Votee_Name, C.username as Voter_Name
FROM Votes V
INNER JOIN UserInfo B ON V.voteeID = B.Id
INNER JOIN UserInfo C on V.voterID = C.id;
I have three different tables in my MySQL database.
table users: (id, score, name)
table teams: (id, title)
table team_Members: (team_id, user_id)
What I would like to do is to have 1 query that finds every team ID a given user ID is member of, along with the following information:
total number of members in that team
the name of the team
users rank within the team (based on score)
EDIT:
Desired output should look like this;
TITLE (of the group) NUM_MEMBERS RANK
------------------------------------------------
Foo bar team 5 2
Another great group 34 17
.
.
.
The query should be based on the users ID.
Help is greatly appreciated
I think this query should get what you ask for
select t.id, t.title, count(m.user_id) members, (
select count(1)
from users u3
inner join team_Members m3 on u3.id = m3.user_id
and m3.team_id = t.id and u3.score > (
select score from users where name = 'Johan'
)
) + 1 score
from teams t
inner join team_Members m on t.id = m.team_id
where t.id in (
select team_id
from team_Members m2
inner join users u2 on m2.user_id = u2.id
where u2.name = 'Johan'
)
group by t.id, t.title
To collect you just need use JOIN
SELECT
u.*, t.*, tm.*
FROM
users u
JOIN
team_Members tm ON u.id = tm.user_id
JOIN
teams t ON t.id = tm.team_id;
To get total of number of that team use COUNT with some group key
Some like that
SELECT
COUNT(t.id), u.*, t.*, tm.*
FROM
users u
JOIN
team_Members tm ON u.id = tm.user_id
JOIN
teams t ON t.id = tm.team_id GROUP BY t.id;
And to rank just:
SELECT
COUNT(t.id) as number_of_members, u.*, t.*, tm.*
FROM
users u
JOIN
team_Members tm ON u.id = tm.user_id
JOIN
teams t ON t.id = tm.team_id
GROUP BY t.id
ORDER BY u.score;