I have looked through some of the other posts on this site and am not seeing exactly what im looking for so here goes.
Lets say i have 2 tables
juser
-----------------------------
userID firstName lastName
-----------------------------
1 billy bob
2 jezze belle
3 bobbie sue
and:
juserrel
---------------------------------------------
id userID relUserID state
---------------------------------------------
1 1 2 approved
2 2 1 retired
3 2 1 approved
4 3 2 approved
What i am trying to do is get a result set that shows each user info about each user in the juser table and adds a column called connections to the result set which shows how many "active" connections a particular user has to another user.
the result i expect based on the tables above is
resultSet
-----------------------------------------------
userID firstName lastName connections
-----------------------------------------------
1 billy bob 2
2 jezze belle 3
3 bobbie sue 1
The query I tried is as follows
select userID, firstName, lastName , coalesce(x.cnt,0) as connections
from juser
left outer join (select count(*) cnt from juserrel where juserrel.userID =
userID or juserrel.relatedUserID = userID and juserrel.state = 'approved')
x on userID = userID
The result set i get looks like this:
resultSet
-----------------------------------------------
userID firstName lastName connections
-----------------------------------------------
1 billy bob 4
2 jezze belle 4
3 bobbie sue 4
Help Please ;)
Try:
select u.userID, u.firstName, u.lastName,
count(case when ur.state = 'approved' then 1 end)
from juser u
inner join juserrel ur on u.userID = ur.userID or u.userID = ur.relUserID
group by u.userID, u.firstName, u.lastName
SQL Fiddle Example
Related
I have three tables, clients, job_allocations and jobs table. I want to select all clients that are not in a particular job, below are my tables.
Clients table
id
Fullname
1
John Doe
2
Jane Doe
3
King James
4
Jere Gray
Jobs table
id
Title
1
Road Construction
2
Repair of Engines
job_allocations table
id
client_id
job_id
1
2
1
2
2
2
3
1
2
4
3
2
I want to select all clients that are not in job_id=2, but when I ran my query, I am getting client id: 2 - Jane Doe again, please how do I solve this?
I did this:
LEFT JOIN job_allocations ON job_allocations.client_id = clients.id
WHERE job_id <> 2 OR job_id IS NULL```
You can use a NOT IN clause as follows:
SELECT *
FROM clients
WHERE id NOT IN (SELECT client_id
FROM job_allocations
WHERE job_id = 2)
Check the demo here.
So you will fetch all clients, but only jobs related to job_id <> 2
This query should work for you:
SELECT client.*
FROM clients
LEFT JOIN job_allocations ON job_allocations.client_id = clients.id and job_id <> 2
Use DISTINCT keyword for selecting unique values
I don't know what the right definition of this is, but its more dynamic than a regular relationship join.
contacts:
id, first_name, last_name
fields:
id, handle, type
field_values:
id, field_id, contact_id, value
The table fields is not that important in this, but wanted to give context.
Example of contacts table:
id first_name last_name
-- ----- --------
1 John Doe
2 Jane Smith
Example of field value table:
id contact_id field_id value
-- ----- -------- ------
1 1 1 Boston
2 1 2 johndoe#mail.com
3 2 1 Seattle
3 2 2 janesmith#mail.com
In this basic example, you can see that there are 2 fields, one for location (boston, seattle) and one for email. When I put them into a JOIN query they look like this
SELECT * FROM contacts LEFT JOIN field_values ON contacts.id = field_values.contact_id;
Example of contacts JOIN field values table:
id first_name last_name field_id value
-- ----- -------- ------ -------
1 John Doe 1 Boston
1 John Doe 2 johndoe#mail.com
2 Jane Smith 1 Seattle
2 Jane Smith 2 janesmith#mail.com
TWO QUESTIONS:
1) How do I ORDER BY the field value. So I want to order by the field email which is field id = 2.
2) Is it possible to get a single row for each contact and each field value as a new column?
Example: Single row per contact?
id first_name last_name field_id(2) field_id(1)
-- ----- -------- ------ -------
1 John Doe johndoe#mail.com Boston
2 Jane Smith janesmith#mail.com Seattle
Single row per contact:
SELECT
contacts.id,
contacts.first_name,
contacts.last_name,
GROUP_CONCAT(IF(field_values.field_id = 2, field_values.value, NULL)) AS email,
GROUP_CONCAT(IF(field_values.field_id = 1, field_values.value, NULL)) AS field_1
FROM contacts
LEFT JOIN field_values ON contacts.id = field_values.contact_id
GROUP BY contacts.id
ORDER BY email;. -- it is optional, only include if you want to sort result by ascending emails.
You may use pivoting logic here to turn out the email and city as separate columns:
SELECT
c.id,
c.first_name,
c.last_name,
MAX(CASE WHEN fv.field_id = 2 THEN fv.value END) AS email,
MAX(CASE WHEN fv.field_id = 1 THEN fv.value END) AS city
FROM contacts c
LEFT JOIN field_values fv
ON c.id = fv.contact_id
GROUP BY
c.id,
c.first_name,
c.last_name;
I have three related tables users, groups and group_members. The users table contains users information and groups table contains the group name and group owner id (ie, users_id). Table group_members contains the members of each groups (user_id and group_id). I tried to load the users details of each group but the result is not correct. My tables are,
users
id firstname lastname email
1 anu mm anu#gmail.com
2 manu mohan manu#gmail.com
3 cinu ab cinu#gmail.com
4 vinu mj vinu#gmail.com
5 vijesh cc vijesh#gmail.com
6 admin admin admin#gmail.com
groups
id user_id name
1 1 group1
2 2 group2
3 2 group3
4 3 group4
group_members
id user_id group_id
1 1 1
2 2 2
3 2 3
4 3 4
5 2 3
7 1 2
8 1 3
9 3 1
But when I tried the bellow query,
select users.firstname,users.lastname,users.email,groups.name as groupname from users inner join groups on groups.user_id = users.id inner join group_members on group_members.group_id = groups.id where groups.id=3 AND users.firstname LIKE 'cin%' OR users.lastname LIKE 'cin%' OR users.email LIKE 'cin%'
getting the result (which is not expected)
firstname lastname email groupname
cinu ab cinu#gmail.com group4
In this case I used the where condition WHERE groups.id =3 but the result takes the group4 (groups.id is 4). Please suggest me a solution.
your have to use () arround your or statements:
where groups.id=3 AND (users.firstname LIKE 'cin%' OR users.lastname LIKE 'cin%' OR users.email LIKE 'cin%')
Because AND has a higher priority you query looks like:
where (groups.id=3 AND users.firstname LIKE 'cin%') OR users.lastname LIKE 'cin%' OR users.email LIKE 'cin%'
And that is not what you want.
Please, check my tables below
users
id name
1 John
2 Peter
3 Predator
phones
id name
1 apple
2 nexus
3 nokva
phones_users
phone_id user_id
1 1
2 1
2 2
3 3
sqlfiddle
Ok, I want to get a result like this:
phone_id phone_name user_id user_name
1 apple 1 John
2 nexus 1 John
2 nexus 2 Peter
I tried one request, but it doesn't work expectedly
select `phones`.`name` as `phone_name`, `phones`.`created_at`, `phones`.`id`, `users`.`name` as `user_name`, `users`.`id` as `user_id` from `phones` left join `phones_users` on (`phones`.`id` = `phones_users`.`phone_id` and `phones_users`.`user_id` = 1) left join `users` on `phones_users`.`phone_id` = `phones`.`id` where `users`.`name` is not null;
I want to get all the phones that have the user with ID = 1, and all users who have phones that belonged to him..
For example, John has apple and nexus and Peter has nexus, I want to get a table with apple, nexus, John, Peter.
THANKS
I attached a copy of phones_users and used IF to distinguish, whether the phone belongs to the same person or not. Based upon that I output the user name and id.
SELECT
`phones_users`.`phone_id`,
`phones`.`name` AS phone_name,
IF(`users`.`id` = `users2`.`id`, `users`.`id`, `users2`.`id`)
AS `user_id`,
IF(`users`.`id` = `users2`.`id`, `users`.`name`, `users2`.`name`)
AS `user_name`
FROM
phones_users
INNER JOIN
phones
ON
phones_users.phone_id=phones.id
INNER JOIN
users
ON
phones_users.user_id=users.id
INNER JOIN -- here I attach the copy of the table
phones_users AS phones_users2
ON
phones_users.phone_id=phones_users2.phone_id
INNER JOIN
users AS users2
ON
phones_users2.user_id=users2.id
WHERE
phones_users.user_id=1;
Output:
+----------+--------------+---------+-----------+
| phone_id | phone_name | user_id | user_name |
+----------+--------------+---------+-----------+
| 1 | apple iphone | 1 | John |
| 2 | nexus | 1 | John |
| 2 | nexus | 2 | Peter |
+----------+--------------+---------+-----------+
-- We know the user details for this part of the query, so just hard-code them instead of query for them
SELECT phone_id, (SELECT name FROM phones WHERE id = pu.phone_id) AS phone_name, 1 AS user_id, "John" AS user_name
FROM phones_users pu
WHERE phone_id IN (SELECT phone_id
FROM phones_users
WHERE user_id = 1)
UNION ALL
SELECT p.id AS phone_id, p.name AS phone_name, u.id AS user_id, u.name AS user_name
FROM phones p, user u
WHERE u.id IN (SELECT user_id
FROM phones_users
WHERE user_id != 1
AND phone_id IN (SELECT phone_id FROM phones_users WHERE user_id = 1))
AND u.id = (SELECT user_id
FROM phones_users
WHERE phone_id = p.id)
Transcribed to English:
Select the phone_id from the table phones_users where this id is in the list of ids of phones used by John and the name of the phone with this id and the values 1 (the ID of John) and his name, "John".
Then, append to that (here it starts to get even more complicated):
the phone id and name and user id and name from the rows resulting from joining the tables phones and users, but only on the rows satisfying the following constraints:
The user id of the row is in the list of user ids of users whose phone's id is the same as the id of the phone John (the user with id 1) uses, i.e. this user is not John but uses the same phone as John,
and the user id is in the list of user ids that are in the table phones_users in the same row as the phone id of the joined row, i.e. this user does indeed use this phone (joining the tables phones and users will give all possible combinations, so we have to remove the rows in which people are with phones they don't use).
I hope you can understand the transcription and the query, if not feel free to leave a comment.
DISCLAIMER: I didn't test the query, it may not work.
I have 3 tables with the following structure:
**users**
id
first_name
last_name
**specialties**
specialty_id
specialty_name
**user_specialties**
user_id
specialty_id
Here is some sample data:
**users**
1 Bill Smith
2 Tom Jones
3 Jill Hayes
**specialties**
1 word
2 web
3 database
**user_specialties**
1 1
2 1
2 3
3 2
3 3
I need to query the data so the specialties are concatinated on one row like the below output
**Desired Result**
Bill Smith word
Tom Jones word,database
Jill Hayes web,database
I am using the following query
SELECT
users.first_name,
users.last_name,
GROUP_CONCAT(specialties.specialtyname)
FROM
users
LEFT JOIN user_specialties ON user_specialties.user_id = users.userid
RIGHT JOIN specialties ON user_specialties.specialty_id = specialties.specialty_id
It is not working...
You're missing a GROUP BY clause. Most likely it should be GROUP BY users.id, and it'd go AFTER the JOIN lines.
I just tested this query
SELECT first_name,last_name,group_concat(specialty_name)
FROM user_specialties map
INNER JOIN specialties skill on user.id = map.user_id
INNER JOIN users user ON skill.specialty_id = map.specialty_id
GROUP BY user.id
Cheers! :-)