SQL Join tablese multiple times on different columns - mysql

I've got two tables:
personal
____________
| id | name |
| 15 | Mike |
| 23 | Rich |
| 35 | Hugo |
and
events
___________________________
| id | driver | translator |
| 22 | 15 | 23 |
| 23 | 35 | 35 |
is there a way to join these two tables to get something like
events
___________________________________
| id | driverName | translatorName |
| 22 | Mike | Rich |
| 23 | Hugo | Hugo |
thx

you can try this
SELECT
e.id
,p1.name driverName
,p2.name translatorName
FROM `events` e
JOIN `personal` p1
ON p1.id=e.driver
JOIN `personal` p2
ON p2.id=e.translator

This will work
select e.id, (select name from Personal where id = e.driver) as DiverName,
p.name as TranslatorName
from Personal p
inner join [events] e on p.id = e.translator

Related

I cant write the correct SQL query correcty

I have 2 table in the database and ı am trying to filter some users according to some criterias.
criterias table
+---------+----------------------+--------------------+----------------------+
| user_id | searching_friendship | searching_practice | conversation_subject |
+---------+----------------------+--------------------+----------------------+
| 31 | | | science |
| 26 | on | on | love |
| 32 | on | off | science |
| 34 | | | |
+---------+----------------------+--------------------+----------------------+
user table
+---------+------------+-----------------------------+---------------+-------------+---------------+--------------+------------------+
| user_id | user_name | user_email | user_password | user_gender | user_language | language_lvl | last_login |
+---------+------------+-----------------------------+---------------+-------------+---------------+--------------+------------------+
| 26 | Furkan | furkanakgun#windowslive.com | 123 | | Türkiye | basic | 16.06.2019 11:57 |
| 31 | sfsdf | asdfasdf#hotmail.com | 123 | Male | Afrikaans | basic | 09.06.2019 20:01 |
| 32 | denemeuser | xxx#hotmail.com | 123 | Male | Amharic | intermediate | 16.06.2019 11:57 |
| 33 | Smith | ssdf | 123 | male | ing | upper | NULL |
| 34 | luser | llll#hotmai.com | 123456 | Male | Afrikaans | basic | 16.06.2019 10:32 |
+---------+------------+-----------------------------+---------------+-------------+---------------+--------------+------------------+
I am trying to match users who have same criterias.What i do is
$userId=$_SESSION['userId'];
$sql="SELECT* FROM criterias WHERE user_id='$userId'";
$query=mysqli_query($conn,$sql);
while($result=mysqli_fetch_assoc($query)){
$friendshipCheck=$result['searching_friendship'];
$pracCheck=$result['searching_practice'];
$conversationSub=$result['conversation_subject'];
}
so I am getting current criterias informations and ı am trying to match with other users like this
SELECT* FROM users,criterias WHERE (users.user_id=criterias.user_id AND users.user_id!='$userId') AND criterias.searching_friendship='$friendshipCheck' OR criterias.searching_practice='$pracCheck'
But it doesnt work. Do you have any idea how to fix this dear friends ?
If you want to get only the users with the same criteria as yours this query should work
SELECT *
FROM users AS u
INNER JOIN criterias AS c ON u.user_id = c.user_id
WHERE u.user_id != '$userId'
AND c.searching_friendship = '$friendshipCheck'
AND c.searching_practice = '$pracCheck'
AND c.conversation_subject = '$conversation_subject'
Providing the expected results vs what you are getting would help proving the best solution.
Here, I am trying to write the query based on the understanding of what you have tried to write in your code:
;WITH CTE AS
(
SELECT C.*
FROM Criterias C
WHERE C.user_id = <user_id_input>
)
SELECT *
FROM User U
INNER JOIN Criterias C
ON U.user_id = C.user_id
WHERE EXISTS (
SELECT 1
FROM CTE
WHERE CTE.searching_friendship = C.searching_friendship
OR CTE.searching_practice = C.searching_practice
)
AND U.user_id != <input_user_id> ;

SELECT just one FROM the LEFT JOINTs +mySQL

Got following Tables in my SQL-Database (simplified):
Table Blogs:
+----+----------------------+----------+
| ID | Date | TitleGer |
+----+----------------------+----------+
| 1 | 2017-04-28 15:09:46 | Huhu |
| 2 | 2017-04-28 15:16:18 | Miau |
| 3 | 2017-04-28 15:17:14 | Kleff |
+----+----------------------+----------+
Table PicturesJoin:
+-------------+---------+---------------------+
| IDPicture | IDBlog | Date |
+-------------+---------+---------------------+
| 86 | 1 | 2017-06-28 17:41:11 |
| 87 | 1 | 2017-06-28 17:41:11 |
+-------------+---------+---------------------+
Table Pictures:
+------+-------------------------+---------------------+
| ID | Filename | Date |
+------+-------------------------+---------------------+
| 86 | 20170512200326_320.jpg | 2017-05-12 20:03:26 |
| 87 | 20170512200326_384.jpg | 2017-05-12 20:03:30 |
+------+-------------------------+---------------------+
PictureJoin "joins" the Picture with the Blog-Table. Now I use following SQL-Command to joine these two Tables (Blog - PictureJoin) / (PictureJoin - Pictures) together.
SELECT
Blogs.ID,
Blogs.Date,
TitleGer,
Pictures.Filename
FROM
Blogs
LEFT JOIN
PicturesJoin ON PicturesJoin.IDBlog = Blogs.ID
LEFT JOIN
Pictures ON Pictures.ID = PicturesJoin.IDPicture
ORDER BY
DATE DESC
The result might look like that:
+------+----------------------+-----------+------------------------+
| ID | Date | TitleGer | Filename |
+------+----------------------+-----------+------------------------+
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_320.jpg |
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_384.jpg |
| 2 | 2017-04-28 15:16:18 | Miau | NULL |
| 3 | 2017-04-28 15:17:14 | Kleff | NULL |
+------+----------------------+-----------+------------------------+
He makes a cross-product out of the available Pictures, which is also logical. But I want him to just use the first Picture he finds. In the end it should look like that:
+------+----------------------+-----------+------------------------+
| ID | Date | TitleGer | Filename |
+------+----------------------+-----------+------------------------+
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_320.jpg |
| 2 | 2017-04-28 15:16:18 | Miau | NULL |
| 3 | 2017-04-28 15:17:14 | Kleff | NULL |
+------+----------------------+-----------+------------------------+
Tried several hours but couldn't get it to work. Please help!
The easiest approach may be to select one IDPicture per IDBlog from PicturesJoin only:
SELECT
b.ID,
b.Date,
b.TitleGer,
p.Filename
FROM Blogs b
LEFT JOIN
(
SELECT
IDBlog,
MIN(IDPicture) AS IDPicture
FROM PicturesJoin
GROUP BY IDBlog
) pj ON pj.IDBlog = b.ID
LEFT JOIN Pictures p ON p.ID = pj.IDPicture
ORDER BY b.Date DESC;
SELECT b.ID,b.Date,b.TitleGer,p.Filename
FROM Blogs b
LEFT JOIN
(
SELECT main_table.*
FROM PicturesJoin main_table LEFT JOIN PicturesJoin child_table
ON (main_table.IDBlog= child_table.IDBlog AND main_table.IDPicture> child_table.IDPicture)
WHERE child_table.id IS NULL
)
OUTER_TABLE ON OUTER_TABLE .IDBlog = b.ID
LEFT JOIN Pictures p ON p.ID = pj.IDPicture
ORDER BY b.Date DESC;
Try above query.

mysql join 3 tables by id

I have 3 tables to join and need some help to make it work, this is my schema:
donations:
+--------------------+------------+
| uid | amount | date |
+---------+----------+------------+
| 1 | 20 | 2013-10-10 |
| 2 | 5 | 2013-10-03 |
| 2 | 50 | 2013-09-25 |
| 2 | 5 | 2013-10-01 |
+---------+----------+------------+
users:
+----+------------+
| id | username |
+----+------------+
| 1 | rob |
| 2 | mike |
+----+------------+
causes:
+--------------------+------------+
| id | uid | cause | <missing cid (cause id)
+---------+----------+------------+
| 1 | 1 | stop war |
| 2 | 2 | love |
| 3 | 2 | hate |
| 4 | 2 | love |
+---------+----------+------------+
Result I want (data cropped for reading purposes)
+---------+-------------+---------+-------------+
| id | username | amount | cause |
+---------+-------------+---------+-------------+
| 1 | rob | 20 | stop war |
| 2 | mike | 5 | love |
+---------+-------------+-----------------------+
etc...
This is my current query, but returns double data:
SELECT i.*, t.cause as tag_name
FROM users i
INNER JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.uid = tti.uid)
EDIT: fixed sql schema on fiddle
http://sqlfiddle.com/#!2/0e06c/1 schema and data
How I can do this?
It seems your table's model is not right. There should be a relation between the Causes and Donations.
If not when you do your joins you will get duplicated rows.
For instance. Your model could look like this:
Donations
+--------------------+------------+
| uid | amount | date | causeId
+---------+----------+------------+
| 1 | 20 | 2013-10-10 | 1
| 2 | 5 | 2013-10-03 | 2
| 2 | 50 | 2013-09-25 | 3
| 2 | 5 | 2013-10-01 | 2
+---------+----------+------------+
causes:
+----------------------+
| id | cause |
+---------+------------+
| 1 | stop war |
| 2 | love |
| 3 | hate |
+---------+------------+
And the right query then should be this
SELECT i.*, t.cause as tag_name
FROM users i
INNER JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.id = tti.causeId)
Try this
SELECT CONCAT(i.username ,' ',i.first_name) `name`,
SUM(tti.amount),
t.cause AS tag_name
FROM users i
LEFT JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.uid = tti.uid)
GROUP BY i.id
Fiddle
You need to match the id from both the users and causes table at the same time, like so:
SELECT i.*, t.cause as tag_name
FROM users i
INNER JOIN donations tti ON (tti.uid = i.id)
INNER JOIN causes t ON (t.uid = tti.uid and t.id = i.id)
Apologies for formatting, I'm typing this on a phone.

MySQL, second INNER JOIN

Hi I trying to do query with couple INNER JOIN, Where is my fault?
SELECT job_tbl.id, accounts.username AS starter, accounts.username AS worker, job_tbl.comment, job_tbl.date, job_tbl.status
FROM job_tbl
INNER JOIN accounts ON job_tbl.starter = accounts.id
INNER JOIN accounts ON job_tbl.worker = accounts.id
job_tbl table here :
+----+---------+--------+---------+------+--------+
| id | starter | worker | comment | date | status |
+----+---------+--------+---------+------+--------+
| 1 | 1 | 3 | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
| 2 | 2 | 1 | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
accounts table here:
+----+------------+-----------+-------+
| id | username | extension | email |
+----+------------+-----------+-------+
| 1 | Julia | 100 | email |
+----+------------+-----------+-------+
| 2 | Eve | 101 | email |
+----+------------+-----------+-------+
| 3 | Max | 102 | email |
+----+------------+-----------+-------+
result I want it to be :
+----+---------+--------+---------+------+--------+
| id | starter | worker | comment | date | status |
+----+---------+--------+---------+------+--------+
| 1 | Julia | Max | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
| 2 | Eve | Julia | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
You're not specifying which accounts table instance to use as starter or worker.
Try this:
SELECT job_tbl.id, job_tbl.description, Starter.username AS starter, Worker.username AS worker, job_tbl.comment, job_tbl.date, job_tbl.status
FROM job_tbl
INNER JOIN accounts AS Starter ON job_tbl.starter = Starter.id
INNER JOIN accounts AS Worker ON job_tbl.worker = Worker.id
The problem is you are joining two table without specifying an ALIAS on table accounts causing ambiguous state.
SELECT a.*,
b.username StarterName,
c.userName WorkerName
FROM job_tbl a
INNER JOIN account b
ON a.starter = b.id
INNER JOIN account c
ON a.worker = c.ID
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins

Joining 3 tables

First off, sorry if this is a near enough duplicate. I've found this question, which nearly does what I want, but I couldn't wrap my head around how to alter it to my needs.
I've got these 3 tables:
cs_Accounts:
+----+-----------------------------+-------------+
| id | email | username |
+----+-----------------------------+-------------+
| 63 | jamasawaffles#googlil.com | jamwaffles2 |
| 64 | jamwghghhfles#goomail.com | jamwaffles3 |
| 65 | dhenddfggdfgetal-pipdfg.com | dhendu9411 |
| 60 | jwapldfgddfgfffles.co.uk | jamwaffles |
+----+-----------------------------+-------------+
cs_Groups:
+----+-----------+------------+-------------+
| id | low_limit | high_limit | name |
+----+-----------+------------+-------------+
| 1 | 0 | 0 | admin |
| 2 | 1 | 50 | developer |
| 3 | 76 | 100 | reviewer |
| 4 | 51 | 75 | beta tester |
| 5 | 1 | 50 | contributor |
+----+-----------+------------+-------------+
cs_Permissions:
+----+---------+----------+
| id | user_id | group_id |
+----+---------+----------+
| 4 | 60 | 4 |
| 3 | 60 | 1 |
| 5 | 60 | 2 |
| 6 | 62 | 1 |
| 7 | 62 | 3 |
+----+---------+----------+
I've been wrestling with a 3 way join for hours now, and I can't get the results I want. I'm looking for this behaviour: a row will be returned for every user from cs_Accounts where there is a row in cs_Permissions that contains their ID and the ID of a group from cs_Groups, as well as the group with the group_id has a high_lmiit and low_limit in a range I can specify.
Using the data in the tables above, we might end up with something like this:
email username cs_Groups.name
----------------------------------------------------------
jwapldfgddfgfffles.co.uk jamwaffles admin
jwapldfgddfgfffles.co.uk jamwaffles developer
jwapldfgddfgfffles.co.uk jamwaffles beta tester
dhenddfggdfgetal-pipdfg.com dhendu9411 admin
dhenddfggdfgetal-pipdfg.com dhendu9411 reviewer
There is an extra condition, however. This condition is where rows are only selected if the group the user belongs to has a high_limit and low_limit with values I can specify using a WHERE clause. As you can see, the table above only contains users with rows in the permissions table.
This feels a lot like homework but with a name like James I'm always willing to help.
select a.email,a.username,g.name
from cs_Accounts a
inner join cs_Permissions p on p.user_id = a.id
inner join cs_Groups g on g.id = p.Group_id
where g.low_limit > 70
and g.high_limt < 120
This is the query
SELECT ac.email, ac.username, gr.name
FROM cs_Accounts AS ac
LEFT JOIN cs_Permissions AS per ON per.user_id = ac.id
INNER JOIN cs_Groups AS gr ON per.user_id = gr.id
You can add a WHERE clause to this query if you want