mysql join table with 2 fk to same table - mysql

Table join:
|ID|admin|user |data|
|1 |00001|00002|XXXX|
admin(fk) = users.id,
user(fk) = users.id.
Table users:
|id |name|pass|type |
|00001|root|1234|admin|
|00002|user|1235|user |
select join.*,users.name as admin,users.name as user from join
left join users on users.id=join.admin
left join users on users.id=join.user
where grrrrrrr
How can I do this?
Original query, I'm trying to run:
SELECT
visits.id,
visits.patient AS patient_id,
visits.doctor AS doctor_id,
visits.date,
visits.time_booked,
visits.time_arrived,
visits.time_start,
visits.time_end,
visits.type_id,
visits.complain,
visits.diagnosis,
visits.note,
visits.stats,
(personal.name WHERE personal.id=visits.patient and personal.role='patient') AS pt_name,
(personal.name WHERE personal.id=visits.doctor and personal.role='doctor') AS dr_name
FROM
visits ,
personal

You have to alias the table users with different aliases. Something like
select
a.*,
u1.name as admin,
u2.name as user
from `join` a
left join users u1 on u1.id = a.admin
left join users u2 on u2.id = a.`user`;
Also you have to escape the table name join, user since they are reserved keywords in MySQL. Try to avoid those names as object names.
SQL Fiddle Demo
This will give you:
| ID | ADMIN | USER | DATA |
----------------------------
| 1 | 1 | 2 | XXXX |
Update
For your query after you updated your question, you have to do this the same way, like this:
SELECT
v.id,
v.patient AS patient_id,
v.doctor AS doctor_id,
v.date,
v.time_booked,
v.time_arrived,
v.time_start,
v.time_end,
v.type_id,
v.complain,
v.diagnosis,
v.note,
v.stats,
pationts.name AS pt_name,
doctors.name AS dr_name
FROM visits v
LEFT JOIN personal pationts ON pationts.id = v.patient
AND pationts.role ='patient'
LEFT JOIN personal doctors ON doctors.id = v.patient
AND doctors.role ='doctor';
Updated SQL Fiddle Demo

Related

How to inner join with not in or not exist in mysql query?

I have some data like this
for user
id | username | email
1 | test | test#test.com
2 | om | test2#test2.com
3 | aa | test3#test3.com
And I have data user biodata like this
id | username | bio
1 | test | test
2 | om | test2
So, I want use not in with inner join for showing data with where user.username not in biodata.username and I try like this but it's error
select user.*, biodata.* from user inner join biodata on user.username = biodata.username where user.username not in biodata.username;
So, how to use that?
This calls for the common LEFT JOIN ... IS NULL pattern.
SELECT u.id, u.username, u.email
FROM user u
LEFT JOIN biodata b ON u.username = b.username
WHERE b.id IS NULL
The LEFT JOIN operation preserves all rows in user, whether or not they have matches in biodata. (By contrast, an ordinary JOIN would suppress rows from user that didn't have matches.) The b.id IS NULL operation filters out the rows that do have matches.
She wants the names (user.username) that are not present in biodata table. Left Join preserves ALL records from table users and MATCHING records fom table biodata (good explanation in W3Schools Left Join). The where clause searches usernames that are not present in biodata:
SELECT u.id, u.username, u.email
FROM user u
LEFT JOIN biodata bd
ON u.username = bd.username
WHERE u.username
NOT IN (select username from biodata);
The correct output is:
id | username | email
3 | aa | test3#test3.com
I belive that you are trying to do an 'EXCEPT'. But some SGBDS like MySQL don't have this option.

how to select one table then join another table mysql

so i have two tables.
users
users_id | firstname | lastname
10001 | mike | lapiz
10002 | tom | jerry
profile
profile_id | department | specialization
10001 | Health Dept | Heart
10002 | Brain Dept | Brain
maybe you're curious why i separate the name of the user and the profile.. i have my on reasons for that.. what i wanted to do is to select my all fields from profile then join the users table
what i want to be the result is
users_id | firstname | lastname | profile_id | department |specialization
10001 | mike | lapiz | 1001 | health dept | heart
this is my query..
$sql = SELECT a.profile_id,a.department,a.specialization FROM `tbl_profile` AS a LEFT JOIN (SELECT users_id,firstname,lastname FROM `tbl_users`) AS b ON a.profile_id = b.users_id
what happen is it only display the profile table.. it is not displaying the other table.. and when i tried to
LEFT JOIN (SELECT b.users_id,b.firstname,b.lastname FROM `tbl_users`) AS b
it give me an error unknown column b.users_id
You misunderstand how a join works.
FROM tbl_profile JOIN tbl_users ON ...
joins the two tables, i.e. combines records on the given condition in ON.
FROM tbl_profile JOIN (SELECT * FROM tbl_users)
does exactly the same. It makes no difference if you join a table directly or join the records of the table, because this means exactly the same.
FROM tbl_profile JOIN (SELECT users_id, firstname, lastname FROM tbl_users)
again does the very same thing. Only that you restrict the columns you can use in the query to the three stated columns. So if there existed more columns in the table, you could not use them in the query's select or where or order by clause anymore.
So a join means just combining records. Which columns you want to show, you put in the select clause:
SELECT * FROM tbl_profile JOIN tbl_users ON ...
selects all columns from both tables.
SELECT p.department FROM tbl_profile p JOIN tbl_users u ON ...
selects only the department.
You want:
SELECT * FROM tbl_users u JOIN tbl_profile p ON p.profile_id = u.user_id
A LEFT JOIN by the way is an outer join where you keep the records from the left table in your results even when there is no match in the right table. In your query you said that you wanted to show profile records too that have no match in the users table, which was certainly not intended.
You should use inner join not nested inner join
$sql = SELECT a.profile_id,a.department,a.specialization,b.users_id,b.firstname,
b.lastname FROM tbl_profile AS a inner join tbl_users b
ON a.profile_id = b.users_id
As you want to list all the columns in both the tables with LEFT OUTER JOIN, the following query will serve your purpose:
SELECT * FROM users LEFT OUTER JOIN profile on users.users_id = profile.profile_id
You can use the alias as well if you want as following:
SELECT * FROM users u LEFT OUTER JOIN profile p on u.users_id = p.profile_id

Mysql select between two table without limiting if record appear on the joined table

I have been trying to figure out how to select data related to one id between to tables without limit it to the joined table. I tried using UNION, Inner join, JOIN, but it limit me to show records that are only in both tables. By example:
Table 1 (users)
id | name | register
1 | John | 2014-03-01
2 | Kate | 2014-03-02
etc..
Table 2 (birthdays by example)
id | user | birthday
1 | 1 | 1989-09-09
Note that kate dont have a record on the birthdays table, if i do:
SELECT U.id, name, register, B.birthday FROM users as U INNER JOIN birthday as B ON B.user = U.id
it will only shows JOHN data, i would like to select all my users and if the record do not exist on the joined table, still be able to select all my users, sort of:
id | name | register | birthday
1 | John | 2014-03-01 | 1989-09-09
2 | kate | 2014-03-02 | null or ''
3
4
etc.
Sorry if its a stupid question but i dont find the light on this one. I would appreciate the help.
Regards
You need a LEFT OUTER JOIN instead of the plain JOIN (also known as INNER JOIN), like this:
SELECT U.id, name, register, B.birthday
FROM users as U
LEFT JOIN birthday as B
ON B.user = U.id
A LEFT JOIN between users and birthday tables will contain all records of the "left" table (users), even if the join-condition does not find any matching record in the "right" table (birthday).
This excellent article on The Code Project will help you a lot: Visual Representation of SQL Joins.
Summary of all JOIN types:
Note: Mysql does not support FULL OUTER JOIN but it can be emulated. Useful articles:
https://stackoverflow.com/a/4796911
http://www.sql-tutorial.ru/en/book_full_join_and_mysql.html
http://www.xaprb.com/blog/2006/05/26/how-to-write-full-outer-join-in-mysql/
Use left outer join instead of inner join..
SELECT U.id, name, register, B.birthday
FROM users as U left join birthday as B ON B.user = U.id

SELECTing SUM Across Two Tables for Each User

I have an application with a users table, credit_purchase table, and credit_spend table. I am trying to get the amount of credits the user currently has.
The credit tables are as follows:
credit_purchase
+----+---------+-------+---------------------+
| id | user_id | coins | timestamp |
+----+---------+-------+---------------------+
credit_spend
+----+---------+-------+---------------------+
| id | user_id | coins | timestamp |
+----+---------+-------+---------------------+
What I'm trying to do is select the SUM(credit_purchase.coins) - SUM(credit_spend.coins) for each user. Right now I have something like this:
SELECT users.*, COALESCE(SUM(credit_purchase.coins) - SUM(credit_spend.coins), 0)
FROM users
LEFT JOIN credit_purchase ON users.id = credit_purchase.user_id
LEFT JOIN credit_spend ON users.id = credit_spend.user_id
GROUP BY users.id
but, it the result is not the correct number. It seems to be SUMing the purchases properly, but multiplying the SUM from the spend by the number of purchases.
What am I doing wrong?
Thanks!
try this:
SELECT users.*,
COALESCE(SUM(credit_purchase.coins) - SUM(credit_spend.coins), 0)
FROM users
LEFT JOIN credit_purchase
ON users.id = credit_purchase.user_id
LEFT JOIN credit_spend
ON users.id = credit_spend.user_id
GROUP BY users.id

Combine Multiple Query Results in MySQL (by column)

I have 4 different queries and each of them return individual unique set of Results.
I need to combine the Query Results with using a single query.
my sample queries are:
1. select cls.* from (calls as cls inner join calls_users as clsusr on cls.id=clsusr.call_id) inner join users as usr on usr.id=cls.assigned_user_id where cls.assigned_user_id='seed_max_id'
2. select mtn.* from (meetings as mtn inner join meetings_users as mtnusr on mtn.id=mtnusr.meeting_id) inner join users as usr on usr.id=mtn.assigned_user_id where mtn.assigned_user_id='seed_max_id'
3. select tsk.* from tasks as tsk inner join users as usr on usr.id=tsk.assigned_user_id where tsk.assigned_user_id='seed_max_id'
4. select nts.* from (notes as nts inner join accounts as acnts on acnts.id=nts.parent_id) inner join users as usr on usr.id=acnts.assigned_user_id where acnts.assigned_user_id='seed_max_id'
I tried the following way, but it didn't work
Combine: SELECT tbl1.*, tbl2.*
from (select cls.* from (calls as cls inner join calls_users as clsusr on cls.id=clsusr.call_id) inner join users as usr on usr.id=cls.assigned_user_id where cls.assigned_user_id='seed_max_id') as tbl1
left outer join
(select mtn.* from (meetings as mtn inner join meetings_users as mtnusr on mtn.id=mtnusr.meeting_id) inner join users as usr on usr.id=mtn.assigned_user_id where mtn.assigned_user_id='seed_max_id') as tbl2
using(assigned_user_id)
i also tried right outer join and other inner joins
I am really stuck, if any one know the solution then please help.
I need the similar result like How can I join two tables with different number of rows in MySQL?.
Data Sample:
From Query 1:
+-------------------------------------------+------------------+-
| Call Name | Call Description |
+-------------------------------------------+------------------+-
| Discuss Review Process | NULL |
| Get More information on the proposed deal | NULL |
| Left a message | NULL |
| Discuss Review Process | NULL |
+-------------------------------------------+------------------+
From Query 2:
+-----------------------+-----------------------------------------------------------
| Meeting Name | Meeting Description
+-----------------------+-----------------------------------------------------------
| Review needs | Meeting to discuss project plan and hash out the details o
| Initial discussion | Meeting to discuss project plan and hash out the details o
| Demo | Meeting to discuss project plan and hash out the details o
| Discuss pricing | Meeting to discuss project plan and hash out the details o
| Review needs | Meeting to discuss project plan and hash out the details o
+-----------------------+-----------------------------------------------------------
i need to combine the columns like the following:
+-------------------------------------------+------------------+-------------------+-------------------+
| Call Name | Call Description |Meeting Name |Meeting Description|
+-------------------------------------------+------------------+-------------------+-------------------+
| Discuss Review Process | NULL |Review needs |Meeting to discuss |
| Get More information on the proposed deal | NULL |Initial discussion |Meeting to discuss |
| Left a message | NULL |Demo |Meeting to discuss |
| NULL | NULL |Discuss pricing |Meeting to discuss |
| NULL | NULL |Review needs |Meeting to discuss |
+-------------------------------------------+------------------+-------------------+-------------------+
The best you can do is a UNION or UNION ALL but this requires them to have the same type and number of columns. For example:
SELECT 'Customer' AS type, id, name FROM customer
UNION ALL
SELECT 'Supplier', id, name FROM supplier
UNION ALL
SELECT 'Employee', id, full_name FROM employee
The column names don't have to match. The aliases from the first part will be used for the rest.
I'll also add that instead of:
select cls.* from (calls as cls inner join calls_users as clsusr on cls.id=clsusr.call_id) inner join users as usr on usr.id=cls.assigned_user_id where cls.assigned_user_id='seed_max_id'
you should remove the unnecessary subquery and just do:
SELECT c.*
FROM calls c
JOIN calls_users cu ONc.id = cu.call_id
WHERE c.assigned_user_id = 'seed_max_id'
There's no need for the extra complexity and the above is eminently more readable.
I assume you want your example to return a single row combining the corresponding entries from all these tables. Try this and tell us if it worked:
select * from users as usr
left outer join (calls as cls
inner join calls_users as clsusr
on cls.id = clsusr.call_id)
on usr.id = cls.assigned_user_id
left outer join (meetings as mtn
inner join meetings_users as mtnusr
on mtn.id = mtnusr.meeting_id)
on usr.id = mtn.assigned_user_id
left outer join tasks as tsk
on usr.id = tsk.assigned_user_id
left outer join (notes as nts
inner join accounts as acnts
on acnts.id=nts.parent_id)
on usr.id = acnts.assigned_user_id
where user.id = 'seed_max_id'