SQL Left Join in a single table without duplicate - mysql

I have a junction table with Users ids and projects ids :
Every user can be on multiple projects.
id|UserID |ProjectID|
1 | 1| 2 |
2 | 2| 3 |
3 | 1| 3 |
4 | 3| 4 |
5 | 3| 2 |
6 | 3| 3 |
7 | 4| 5 |
Is it possible to return, with a single sql request all the id of user who are in the same projects as me ?
For example here, return me :
user 3, because he is in the projects 2 and 3 with me
user 2, because he is in the project 3 with me
I tried tu use DISTINCT with LEFT JOIN, but i can't find how to use it with only one table...
Thanks

There are usually a few ways you can achieve something like this in sql. The first method is one that I would have written, just to show you an alternate way of thinking about it. I also wrote a left join as you were attempting to show you that method as well.
Method #1
SELECT DISTINCT UserID
FROM Table
WHERE ProjectID IN (SELECT DISTINCT ProjectID FROM Table WHERE UserID = me)
Method #2
SELECT DISTINCT others.UserID
FROM Table myself
LEFT JOIN Table others ON myself.ProjectID = others.ProjectID
WHERE myself.UserID = me

cant think of anything better for now
declare #searchingId int;
set #searchingId = 1
select distinct t2.UserId
from
(select t1.ProjectId
from [Table] as t1
where t1.UserId = #searchingId) as projects
join [Table] as t2 on projects.ProjectId = t2.ProjectId
where t2.UserId != #searchingId

I would use a simple join:
select distinct upr.userid
from userprojects upr join
userprojects upr2
on upr2.projectid = upr.projectid and
upr2.userid = #me;
If you want to, say, count the number of matching projects, use group by:
select upr.userid, count(*)
from userprojects upr join
userprojects upr2
on upr.projectid = upr.projectid and
upr2.userid = #me
group by upr.userid;

Related

JOIN in two tables in MySQL

I have a two tables in MySQL. I want to create a SELECT that will work in the following way:
Select from the table s_articles_supplier those lines whose id is equal to the active = 1
s_articles_supplier:
id | name
100 | Nike
101 | Adidas
s_articles:
supplierID | active
100 | 1
101 | 0
Use simple join with where condition
select a.id, name from s_articles_supplier a
inner join s_articles b on a.id=b.id
where active=1
You have to use inner join in following way for expected result
SELECT id, name FROM s_articles_supplier
INNER JOIN s_articles ON s_articles_supplier.id=s_articles.supplierID
WHERE s_articles.active=1
Hope it helps you

Joining 2 tables with same id PDO

I am sorry this is not a high quality question and I know I am risking downvotes, but I am trying to learn as I go. I am currently working on a side project and stumbled into a situation I am not sure of.
I have two tables and need to call the data from both sharing the same id number (different names)
I will now attempt to give an example
Table 1
| psid | idd |
| 1 | 999 |
| 2 | 42 |
Table 2
| aid | other |
| 999 | hello world |
| 42 | welcome |
I am trying to link idd and aid whilst displaying all rows from table one
Example
id = 1 / Title : hello world
id = 2 / Title : welcome
I am not sure if this can be achieved with a single query to the database I have tried adding a second but it goes in a nonstop loop.
I have not done much searching as not sure what to search for.
Thanks and sorry
Cartesian Join
SQLFiddle
select
table1.*,
table2.*
from
table1,
table2
where
table1.idd = table2.aid and
table1.idd = :id
Or Left Join
SQL Fiddle
select
t1.*,
t2.*
from
table1 t1
left join
table2 t2
on
t1.idd = t2.aid
where
t1.idd = :id
SELECT table1.psid, table2.other FROM table1
JOIN table2 ON table1.idd = table2.aid
WHERE table1.idd= 'X' AND table2.aid = 'X'
this should JOIN the two tables together and by specifying the matching id's for each table in the WHERE clause should get the relevant information.
EDIT fixed SQL

MySQL select row with two matching joined rows from another table

Hey I try to select a row from a table with two matching entries on another one.
The structure is as following:
----------------- ---------------------
| messagegroups | | user_messagegroup |
| | | |
| - id | | - id |
| - status | | - user_id |
| | | - messagegroup_id |
----------------- | |
---------------------
There exist two rows in user_messagegroup with the ids of two users and both times the same messagegroup_id.
I would like to select the messagegroup where this two users are inside.
I dont get it.. so I would appreciate some help ;)
The specification you provide isn't very clear.
You say "with the ids of two users"... if we take that to mean you have two user_id values you want to supply in the query, then one way to to find the messagegroups that contain these two specific users:
SELECT g.id
, g.status
FROM messagegroups g
JOIN ( SELECT u.messagegroup_id
FROM user_messagegroup u
WHERE u.user_id IN (42, 11)
GROUP BY u.messagegroup_id
HAVING COUNT(DISTINCT u.user_id) = 2
) c
ON c.messagegroup_id = g.id
The returned messagegroups could also contain other users, besides the two that were specified.
If you want to return messagegroups that contain ONLY these two users, and no other users...
SELECT g.id
, g.status
FROM messagegroups g
JOIN ( SELECT u.messagegroup_id
FROM user_messagegroup u
WHERE u.user_id IS NOT NULL
GROUP BY u.messagegroup_id
HAVING COUNT(DISTINCT IF(u.user_id IN (42,11),u.user_id,NULL)) = 2
AND COUNT(DISTINCT u.user_id) = 2
) c
ON c.messagegroup_id = g.id
For improved performance, you'll want suitable indexes on the tables, and it may be possible to rewrite these to eliminate the inline view.
Also, if you only need the messagegroup_id value, you could get that from just the inline view query, without the need for the outer query and the join operation to the messagegroups table.

MySQL join multiple rows from one table while selecting only a single row from the others

Maybe a bit of a strange title description, but i basically want to achieve something the GROUP_CONCAT() function does, only then keep the double entries.
I have four tables i want to join, client, doctor, physio and records
Depending on the variable $client i want to get the client details, attending doctor and therapist (one single row from three tables) and join all records for that user.
Say that in this case the $client = 1. The records table has five records where the column r_client_id = 1. If i run a query like below i only get one record from the records table, namely the first occurrence where r_client_id = 1 (which makes sense of course):
SELECT
client.c_id, client.c_name
doctor.d_name,
physio.p_name,
records.r_record
FROM
adm_clients AS client
INNER JOIN
norm_client_doctor AS ncd ON ncd.ncd_client_id = client.c_id
INNER JOIN
adm_doctor AS doctor ON doctor.d_id = ncd.ncd_doctor_id
INNER JOIN
norm_client_physio AS ncp ON ncp.ncp_client_id = client.c_id
INNER JOIN
adm_physio AS physio ON physio.p_id = ncp.ncp_physio_id
LEFT JOIN
adm_doctor_records AS records ON records.r_client_id = client.c_id
WHERE
client.c_id = '".$client."'
Now assume the five records where r_client_id = 1 are like so:
+------+-------------+-------------------+----------+
| r_id | r_client_id | r_record | r_date |
+------+-------------+-------------------+----------+
| 1 | 1 | regular visit | 10/10/12 |
+------+-------------+-------------------+----------+
| 3 | 1 | emergency control | 24/10/12 |
+------+-------------+-------------------+----------+
| 7 | 1 | regular visit | 08/09/12 |
+------+-------------+-------------------+----------+
| 18 | 1 | delivery | 03/01/12 |
+------+-------------+-------------------+----------+
| 20 | 1 | health checkup | 10/12/11 |
+------+-------------+-------------------+----------+
I want my output to be in an array like so:
Client 1
- Name Doctor
- Name Physio
Records
- Emergency control, 24/10/12
- Regular visit, 10/10/12
- Regular visit, 08/09/12
- Delivery, 03/01/12
- Health checkup, 10/12/11
The closest one i can image is a to add a GROUP_CONCAT() on the records, but that, of course, groups the 'regular visit', so i'll get 4 rows instead of 5
GROUP_CONCAT(DISTINCT records.r_record SEPARATOR '|')
[..]
echo(str_replace("|","<br>",$show->r_record));
Anybody an idea how to display all the matching records? I have the feeling i'm close, but i'm out of options by now..
Edit:
I forgot to mention that when i remove the DISTINCT, it displays all the records twice..
SOLVED:
Got it working like so:
GROUP_CONCAT(DISTINCT
CONCAT (records.r_date, '~', records.r_record, '~', records.r_paraph)
SEPARATOR '|') AS clientDoctorRecords,
Try:
SELECT
client.c_id, client.c_name
doctor.d_name,
physio.p_name,
GROUP_CONCAT(records.r_record)
FROM
adm_clients AS client
INNER JOIN
norm_client_doctor AS ncd ON ncd.ncd_client_id = client.c_id
INNER JOIN
adm_doctor AS doctor ON doctor.d_id = ncd.ncd_doctor_id
INNER JOIN
norm_client_physio AS ncp ON ncp.ncp_client_id = client.c_id
INNER JOIN
adm_physio AS physio ON physio.p_id = ncp.ncp_physio_id
LEFT JOIN
adm_doctor_records AS records ON records.r_client_id = client.c_id
WHERE
client.c_id = '".$client."'
GROUP BY
client.c_id
If you want r_date to come along with record in one column, then you can use plain CONCAT first and then do a GROUP_CONCAT on it.

MySQL - select 3 tables with correct left join syntax

Hope you can help me with correct syntax of a SQL query (using MySQL 5.5.25).
I have 3 tables:
data
data_tmp
users
data table is empty - has it's own structure but no rows
data:
id | name | who
----------------
data_tmp:
id | cars | who
---------------
1 | lambo| 2
users
who | name |
------------
2 | john
My query is:
SELECT DISTINCT
users.name,
(SELECT count(id) FROM data WHERE who = 1) as number,
data_tmp.cars
FROM
users, data, data_tmp
WHERE
users.who = 2
AND data_tmp.who = 2
AND data.who = 2
This of course returns an empty result (there is no row that suits to all parameters because data is empty).
What I would like to achieve is:
users.name | number | data_tmp.cars |
-------------------------------------
john | 0 | lambo |
I am sure I have to - in some way - use LEFT JOIN but can't find correct syntax. Hope you can help me.
Kalreg
give this a try (without using subquery)
SELECT a.name, b.cars, count(c.id) as number
FROM users a
INNER JOIN data_tmp b
on a.who = b.who
LEFT JOIN data c
on a.who = c.who AND
a.name = c.name
WHERE a.who = 2
GROUP BY a.name, b.cars
this works on different servers:
MSSQL SERVER # SQLFIDDLE
MYSQL # SQLFIDDLE
Your assumption is right: you have to use left JOIN, in this way :
SELECT DISTINCT users.name, (SELECT count(id) FROM data WHERE who = 1) as number, data_tmp.cars
FROM users
JOIN data_tmp USING (who)
LEFT JOIN data USING(who)
WHERE users.who = 2