Joining two tables by id in mysql - mysql

I have two tables like this:
Table_users
id | firstname | lastname
1 | John | Doe
2 | Eve | Adam
table_shifts
date | dayshift | nightshift
2014-09-17 | 1 | 2
2014-09-18 | 2 | 1
And I want this as a result:
table_shifts_overview
date | dayshift | nightshift
2014-09-17 | John Doe | Eve Adam
Where date = '2014-09-17'
I tried this with with JOIN and a subquery, but it didn't work out. Any halp would be appreciated.

Try this query
SELECT TS.date, CONCAT(TU1.firstname,' ', TU1.lastname) AS dayshift, CONCAT(TU2.firstname, ' ', TU2.lastname) AS nightshift
FROM table_shifts TS
INNER JOIN table_users TU1 on TU1.ID= TS.dayShift
INNER JOIN table_users TU2 on TU2.id= TS.NightShift
WHERE TS.Date = '2014-09-17'

SELECT S.date,
concat(U1.FirstName,' ', U1.LastName) dayshift,
concat(U2.FirstName,' ', U2.LastName) nightshift
FROM table_Shifts S
INNER JOIN table_users U1
on U1.ID= S.dayShift
INNER JOIn table_users U2
on U2.id= S.NightShift
WHERE S.Date = '2014-09-17'

You can join the same table multiple times by aliasing it:
SELECT date, u1.firstname, u1.lastname, u2.firstname, u2.lastname
FROM table_shifts
INNER JOIN table_users AS u1 ON u1.id = dayshift.id
INNER JOIN table_users AS u2 ON u2.id = nightshift.id

You can use implicit join:
SELECT s.date,
CONCAT(u_day.firstname, ' ', u_day.lastname) AS dayshift,
CONCAT(u_night.firstname, ' ', u_night.lastname) AS nightshift
FROM shifts s, users u_day, users u_night
WHERE s.dayshift = u_day.id AND s.nightshift = u_night.id
AND s.date = '2014-09-17'
Or explicit join:
SELECT s.date,
CONCAT(u_day.firstname, ' ', u_day.lastname) AS dayshift,
CONCAT(u_night.firstname, ' ', u_night.lastname) AS nightshift
FROM shifts s
INNER JOIN users u_day ON (s.dayshift = u_day.id)
INNER JOIN users u_night ON (s.nightshift = u_night.id)
WHERE s.date = '2014-09-17'
Note that the keyword INNER is optional in the last query.
Here is the MySQL documentation about JOIN syntax:
http://dev.mysql.com/doc/refman/5.6/en/join.html

You can try;
SELECT ts.date,
contact(tu.firstname ,' ', tu.lastname) AS dayshift,
contact(tu2.firstname ,' ', tu2.lastname) AS nightshift
FROM table_shifts ts, Table_users tu, Table_users tu2
WHERE ts.dayshift = tu.id AND
ts.nighshift = tu2.id AND
ts.date = '2014-09-17'

Related

MySQL select group concat?

I am trying to do a select from two tables. I have two tables:
select * from igw41_users;
+-----+------------+----------+-----------------------------+--------------------------------------------------------------+-------+-----------+---------------------+---------------------+------------+--------------------------------------------------------------------------------------------------------------------------------+---------------------+------------+--------+------+--------------+
| id | name | username | email | password | block | sendEmail | registerDate | lastvisitDate | activation | params | lastResetTime | resetCount | otpKey | otep | requireReset |
17 John Doe AAAAAA nothing else is needed from this table.
select * from igw41_user_profiles;
+---------+----------------------+-----------------------+----------+
| user_id | profile_key | profile_value | ordering |
17 profile.account_type "2" 4
17 profile.postal_code "75055" 1
I need to get id (from igw41_users), username igw41_users , postal_code (from igw41_user_profiles) and account_type (from igw41_user_profiles). But the info I need is in profile_values for each igw41_user_profiles.user_id that matches igw41_users.id.
select id, username, GROUP_CONCAT(profile_value SEPARATOR ',')
from igw41_users
left join igw41_user_profiles on igw41_users.id = igw41_user_profiles.user_id and igw41_user_profiles.profile_key = 'profile.account_type'
group by username;
this gives me the account_type, but I can't figure out how to get the postal_code If I do a right join it gives me: ERROR 1066 (42000): Not unique table/alias: 'igw41_user_profiles'
This is what I tried to get both profile values:
select id, username, GROUP_CONCAT(profile_value SEPARATOR ',')
from igw41_users
left join igw41_user_profiles on igw41_users.id = igw41_user_profiles.user_id and igw41_user_profiles.profile_key = 'profile.account_type'
right join igw41_user_profiles on igw41_users.id = igw41_user_profiles.user_id and igw41_user_profiles.profile_key = 'profile.postal_code'
group by username;
Thanks in advance.
take and igw41_user_profiles.profile_key = 'profile.account_type' out of your first query
If you wish to test for both use in
and igw41_user_profiles.profile_key in('profile.account_type','profile.postal_code')
In common way when you need to join same table more then once you need to use aliases for each join:
select id, username, GROUP_CONCAT(profile_value SEPARATOR ',')
from igw41_users
left join igw41_user_profiles p1
on igw41_users.id = p1.user_id and
p1.profile_key = 'profile.account_type'
right join igw41_user_profiles p2
on igw41_users.id = p2.user_id and
p2.profile_key = 'profile.postal_code'
group by username;
In this case the second join is redundant:
select id, username, GROUP_CONCAT(profile_value SEPARATOR ',')
from igw41_users
left join igw41_user_profiles p1 on igw41_users.id = p1.user_id
where
p1.profile_key = 'profile.account_type' OR
p1.profile_key = 'profile.postal_code'
group by username;

GROUP_CONCAT multiple where condition particular data

Query
(SELECT
pid,
visitdate,
GROUP_CONCAT(tooth, ' - ', problem, ' - ', recomendation SEPARATOR ', <br>')
FROM tbl_finds_d) V
WHERE V.pid='1' AND V.visitdate = '16-03-2020'
TABLE
Want to get WHERE pid=1 AND visitdate=16-03-2020
pid visitdate tooth problem recomendation
1 16-03-2020 13 ASX DFFF
1 16-03-2020 12 JHJ HJLP
2 12-03-2020 14 JKB IJLHJ
UPDATE (copied from the comment)
SELECT *
FROM pendingtreatment A
INNER JOIN tbl_finds_m B ON B.pid = '$pid'
AND B.visitdate = '$visitdate'
INNER JOIN treatmentadviced C ON C.pid = '$pid'
AND C.visitdate = '$visitdate'
INNER JOIN treatmentlist D ON D.pid = '$pid'
AND D.visitdate = '$visitdate'
INNER JOIN tbl_appointments E ON E.pid = '$pid'
AND E.visitdate = '$visitdate'
INNER JOIN ( SELECT pid,
visitdate,
GROUP_CONCAT(tooth, ' - ', problem, ' - ', recomendation SEPARATOR ', <br>')
FROM tbl_finds_d V
WHERE V.pid='$pid'
AND V.visitdate = '$visitdate') F
WHERE A.pid = '$pid'
AND A.visitdate = '$visitdate'

COnditional JOIN query in MySQL

I have two mysql tables
user:
|--------------------------------|
| id | name | type | ruser_type |
|--------------------------------|
| 1 | Admin | a | |
| 2 | | r | c |
|--------------------------------|
customer
|-------------------------|
| id | name | user_id |
|-------------------------|
| 1 | Sam | 2 |
|-------------------------|
If user.type is 'a' or 's', then its admin user whose name is in user table.
If user.type is 'r' and ruser_type is 'c', then its regular user which has a relation in customer table where customer.user_id = user.id
I want a query which would run a conditional join.
If user.type is 'a' or 's', then name would be fetched from user table.
If user.type is 'r' and and ruser_type is 'c', then name would be fetched from customer table with the JOIN condition customer.user_id = user.id.
For this, I have written a query like this:-
SELECT users.fname as adminFname, customers.fname as customerFname, users.type FROM users
LEFT JOIN customers ON (customers.user_id = users.id AND
(
(users.type = 'r' AND users.ruser_type = 'c')
OR users.type = 'a'
OR users.type = 's'
)
)
WHERE users.id = 1
Is there any possibility to optimize the query more?
Also, how can I write this query using Laravel eloquent?
FWIW, I find this marginally easier to read...
SELECT u.fname adminFname
, c.fname customerFname
, u.type
FROM users u
LEFT
JOIN customers c
ON c.user_id = u.id
WHERE u.id = 1
AND (
(u.type = 'r' AND u.ruser_type = 'c')
OR (u.type IN('a','s'))
)
I have written two sql query hope this will help you
SELECT CASE CU.type WHEN 'a' OR 's' THEN CU.name END AS name,
CASE WHEN CU.type = 'r' AND CU.ruser_type = 'c' THEN CR.name END AS cust_name, CU.type
FROM
user AS CU
LEFT JOIN customer AS CR ON CR.user_id = CU.id
In this you'll get result like this,
name cust_name type
Sam r
Admin a
and i have wrote another query like this,
SELECT CASE WHEN CU.type = 'a' OR 's' THEN CU.name ELSE CR.name END AS name, CU.type
FROM
user AS CU
LEFT JOIN customer AS CR ON CR.user_id = CU.id
In this you'll get result like this
name type
Sam r
Admin a
DB File Link
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=b02d931b68a4f70d8b4a84144c60a572
This will give you required result for all users:
SELECT u.fname adminFname
, c.fname customerFname
, u.type
FROM users u
LEFT JOIN customers c
ON (u.type = 'r' AND u.ruser_type = 'c' AND c.user_id = u.id)
Add where condition as required.
You can even simplify it further to get common firstName column in output:
SELECT COALESCE(u.fname, c.fname) firstName, u.type
FROM users u
LEFT JOIN customers c
ON (u.type = 'r' AND u.ruser_type = 'c' AND c.user_id = u.id)

Displaying mySQL LEFT JOIN with multiple matches in second table correctly

Here's our DB setup:
members:
addresses:
titles:
And this is the output we need:
Mr John Doe Msc A-1100 Vienna (A00025)
Mrs Jamie Smith A-4040 Linz (A00026)
Jack Jones A-5020 Salzburg (A00027)
This is our mySQL statement so far:
SELECT T1.member_id, T1.surname, T1.firstname, T2.country, T2.zip, T2.town,
T3.titel, T3.position FROM members T1
LEFT JOIN addresses T2
ON T1.member_id = T2.member_id
LEFT JOIN titles T3
ON T1.member_id = T3.member_id
WHERE T2.type = "invoice"
This gives us:
Mr John Doe A-1100 Vienna (A00025)
John Doe MSc A-1100 Vienna (A00025)
Mrs Jamie Smith A-4040 Linz (A00026)
Jack Jones A-5020 Salzburg (A00027)
How do we prevent John Doe from being listed twice?
How do we get both titles in the same line?
Thanks for any help!!
The key here is to join the titles table as many times as there can be different title positions so that you can access every different title/position from a different source.
If you want to produce a string like Mr Doe John MSc A-1100 Vienna (A00025) from your query you can use the concat function to build it.
SELECT
concat(
case when t1.titel is null then '' else t1.titel end,
case when t1.titel is null then '' else ' ' end,
m.firstname, ' ',
m.surname, ' ',
case when t2.titel is null then '' else t2.titel end,
case when t2.titel is null then '' else ' ' end,
a.country, '-', a.zip, ' ',
a.town,
' (', m.member_id , ')'
) AS LongString
FROM members m
JOIN addresses a
ON m.member_id = a.member_id AND a.type = 'invoice'
LEFT JOIN titles t1
ON m.member_id = t1.member_id AND t1.position = 'Before'
LEFT JOIN titles t2
ON m.member_id = t2.member_id AND t2.position = 'After'
Sample SQL Fiddle
Sample output:
| LONGSTRING |
|----------------------------------------|
| Mr John Doe MSc A-1100 Vienna (A00025) |
| Mrs Jamie Smith A-4040 Linz (A00026) |
| Jack Jones A-5020 Salzburg (A00027) |
Assuming you have a maximum of only 1 title before and 1 title after:
SELECT T1.member_id, T1.surname, T1.firstname,
T2.country, T2.zip, T2.town,
T3.titel AS titelBefore,
T4.titel AS titelAfter,
FROM members T1
INNER JOIN addresses T2 ON (T1.member_id = T2.member_id)
LEFT JOIN titles T3 ON (T1.member_id = T3.member_id AND T3.position = "before")
LEFT JOIN titles T4 ON (T1.member_id = T4.member_id AND T4.position = "after")
WHERE T2.type = "invoice"
Please note the INNER JOIN for addresses, you don't need a LEFT JOIN since you state T2.type = "invoice" in your WHERE

repeated values with group_concat and joins

i have a little problem with the following Query. It returns multiple values.
Here is the result I'm receiving:
+----+--------------+--------+--------+---------------------+----------+------------------+
| id | company | county | vm | os | products | sn |
+----+--------------+--------+--------+---------------------+----------+------------------+
| 1 | ABC Corp | USA | VMW | Linux, Linux, Linux | 3 | A123, B234, A343 |
| 2 | DEF Corp | USA | CIT | Windows | 1 | I223 |
+----+--------------+--------+--------+---------------------+----------+------------------+
As you can see, the first line shows 3 times Linux, but this should be only listed once. I've seen that this problem only occurs if the customer has more than 1 product. I think i have to Group my Query or something like this, but i don't know how.
Here is my Query:
SELECT
customer.id,
customer.company,
countries.en AS country,
vmenv.name AS vm,
GROUP_CONCAT(operatingsystems.name SEPARATOR ', ') AS os,
COUNT(device2customer.sn) AS products,
GROUP_CONCAT(device2customer.sn SEPARATOR ', ') AS sn
FROM
customer
LEFT JOIN
countries
ON
customer.country = countries.id
LEFT JOIN
vmenv2kunden
ON
vmenv2kunden.customerid = customer.id
LEFT JOIN
vmenv
ON
vmenv2kunden.vmenvnr = vmenv.id
LEFT JOIN
operatingsystems2customer
ON
operatingsystems2customer.customerid = customer.id
LEFT JOIN
operatingsystems
ON
operatingsystems2customer.osnr = operatingsystems.id
LEFT JOIN
device2customer
ON
device2customer.kundenid = customer.id
GROUP BY
customer.id
In your query change the group_concat statement to
GROUP_CONCAT(DISTINCT operatingsystems.name SEPARATOR ', ') AS os,
COUNT(DISTINCT device2customer.sn) AS products,
GROUP_CONCAT(DISTINCT device2customer.sn SEPARATOR ', ') AS sn
By adding the DISTINCT key word it should work for you
you just need yo use distinct in Group_concat.
Please try the below updated Query.
SELECT
customer.id,
customer.company,
countries.en AS country,
vmenv.name AS vm,
GROUP_CONCAT(distinct operatingsystems.name SEPARATOR ', ') AS os,
COUNT(device2customer.sn) AS products,
GROUP_CONCAT(device2customer.sn SEPARATOR ', ') AS sn
FROM
customer
LEFT JOIN
countries
ON
customer.country = countries.id
LEFT JOIN
vmenv2kunden
ON
vmenv2kunden.customerid = customer.id
LEFT JOIN
vmenv
ON
vmenv2kunden.vmenvnr = vmenv.id
LEFT JOIN
operatingsystems2customer
ON
operatingsystems2customer.customerid = customer.id
LEFT JOIN
operatingsystems
ON
operatingsystems2customer.osnr = operatingsystems.id
LEFT JOIN
device2customer
ON
device2customer.kundenid = customer.id
GROUP BY
customer.id