I am new to this kind of relational type of database design. I just designed the database in this manner. However, I am quite confused on this JOIN of MySQL. What should be my query to join all this table. If you can see the table users is the reference of all the tables.
users
+----------+----------------+-----------------+
| users_id | users_level_id | users_status_id |
+----------+----------------+-----------------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
+----------+----------------+-----------------+
users_credentials
+----------+---------------------------+-----------------------------+----------------------------+
| users_id | users_credential_username | users_credential_email | users_credential_password |
+----------+---------------------------+-----------------------------+----------------------------+
| 1 | super | super#gmail.com | $5$e94e9e$vptscyHjm8rdX0j6 |
| 2 | admin | admin#gmail.com | $5$fVuOmySyC0PttbiMn8in0k7 |
+----------+---------------------------+-----------------------------+----------------------------+
users_level
+----------------+-------------------------+
| users_level_id | users_level_description |
+----------------+-------------------------+
| 1 | Super Administrator |
| 2 | Administrator |
+----------------+-------------------------+
users_status
+-----------------+--------------------------+
| users_status_id | users_status_description |
+-----------------+--------------------------+
| 0 | Disabled |
| 1 | Enabled |
+-----------------+--------------------------+
Try this
SELECT u.*, uc.*, ul.*, us.*
FROM users u
INNER JOIN users_credentials uc
ON u.users_id = uc.users_id
INNER JOIN users_level ul
ON u.users_level_id = ul.users_level_id
INNER JOIN users_status us
ON u.users_status_id = us.users_status_id
Note the use INNER JOIN: this means that if a user does not have corresponing record on joined table it won't be shown; if you need to return every user even without matching record on related tables, change INNER JOIN with LEFT JOIN.
EDITED after user comment:
If you want to return just some column, define it as this example
SELECT uc.users_credential_username AS username,
uc.users_credential_email AS email,
uc.users_credential_password AS pwd,
ul.users_level_description AS level,
us.users_status_description AS status
This is a simple query that will join all of them
select *
from users
left join users_credentials
on users_credentials.users_id = users.users_id
left join users_level
on users_level.users_level_id = users.users_level_id
left join users_status
on users_status.users_status_id = users.users_status_id
EDIT
if you want to fetch data from different tables
user this
select users.* , users_credentials.* , users_level.* , users_status.*
from users
left join users_credentials
on users_credentials.users_id = users.users_id
left join users_level
on users_level.users_level_id = users.users_level_id
left join users_status
on users_status.users_status_id = users.users_status_id
I think this look like this :
SELECT * FROM users
LEFT JOIN user_credentials ON users.user_id = user_credential.user_id
LEFT JOIN user_level ON users.users_level_id = users_level.users_level_id
and so on..
Use this type of query....
SELECT c.*, l.*, s.*
FROM users AS u
INNER JOIN users_credentials AS c ON (u.users_id = C.users_id)
INNER JOIN users_level AS l ON (u.users_level_id= l.users_level_id)
INNER JOIN users_status AS s ON (u.users_status_id= s.users_status_id)
Where you can specify the field what you want in .* ...
Join is used to fetch data from normalized tables which have foreign key relation with the reference table.
For the above table with join you can fetch data among two tables with the help of reference table.
For example
Select * from users a JOIN users_credentials b
ON a.user_id=b.user_id JOIN users_level c
ON c.users_level_id=a.users_level_id
where users_credential_username='super';
The result of this query will give you the detail like users_level_description for the user with users_credential_username=super.
Related
How to join different tables with pivote table
I have 4 tables like
users
id | name |
-------------
1 | abc |
2 | ccc |
user_profile
id | user_id | email |
-------------------------------
1 | 1 | abc#gmail.com
2 | 2 | ccc#gmail.com
skills
id | skill_name |
--------------------------
1 | java |
2 | php |
user_skills
user_id | skill_id |
---------------------------
1 | 1 |
1 | 2 |
2 | 1 |
The result should be
name | email | skills |
----------------------------------
abc |abc#gmail.com | java, php |
ccc |ccc#gmail.com | java |
I am able to join multiple tables but I have problem joining pivote
I have tried below with query
SELECT users.name,user_profiles.email, group_concat(programs.name)
from users
JOIN user_profiles on user_profiles.user_id = users.id
LEFT JOIN user_skills on user_skills.user_id = users.id
LEFT JOIN skills on user_skills.skill_id = skills.id
GROUP BY users.id
Can anyone help me on this please??Thanks
You need GROUP_CONCAT to generate the CSV list of skills:
SELECT
u.name,
up.email,
GROUP_CONCAT(s.skill_name) AS skills
FROM users u
INNER JOIN user_profile up
ON u.id = up.user_id
LEFT JOIN user_skills us
ON u.id = us.user_id
INNER JOIN skills s
ON us.skill_id = s.id
GROUP BY
u.id, u.name, up.email;
Demo
Note that I group by both the user's id and name, because perhaps two users happen to have the same name. Follow the link below for a running SQLFiddle.
Your query should work. Perhaps the problem is the reference to programs rather than skills:
select u.name, up.email, group_concat(s.name)
from users u join
user_profiles up
on up.user_id = u.id left join
user_skills us
on us.user_id = u.id left join
skills s
on us.skill_id = s.id
group by u.name, up.email;
i've been trying to join to one table but using two different columns. Ok so i've got the following tables:
Users:
--------------------------------------------------
| user_id | name |
--------------------------------------------------
| 1 | Bob |
--------------------------------------------------
| 2 | John |
--------------------------------------------------
Table2:
--------------------------------------------------
| user_one | user_two | field3 |
--------------------------------------------------
| 1 | 2 | something here |
--------------------------------------------------
Is their any way to join the user's table using both fields. Something like this:
SELECT
table2.*,
users.name
FROM table2
INNER JOIN users
ON users.user_id = table2.user_one AND users.user_id = table2.user_two
I've tried the above query but it doesn't return anything.
Edit
I would want to return something like this:
--------------------------------------------------
| user_one_name | user_two_name | field3 |
--------------------------------------------------
| Bob | John | something here|
--------------------------------------------------
You need two joins. This is often done using left join in case one or both user ids do not match:
SELECT t2.*, u1.name as user1name, u2.name as user2name
FROM table2 t2 LEFT JOIN
users u1
ON u1.user_id = t2.user_one LEFT JOIN
users u2
ON u2.user_id = t2.user_two;
It sounds like you want to get the name of both users in a single row. Assuming so, then you can join to the users table multiple times:
SELECT
table2.*,
u1.name user1name,
u2.name user2name
FROM table2 t2
INNER JOIN users u1 ON u1.user_id = t2.user_one
INNER JOIN users u2 ON u2.user_id = t2.user_two
As mentioned in a comment, if it's possible you have user ids in table2 that do not exist in the users table (or you allow null values to be stored), you can use an outer join instead to get your desired results.
However, if that is the case, you may have larger issues with your database design. You shouldn't have foreign keys that don't have corresponding primary keys unless those are perhaps nullable.
i have two table here is table_user and table_feedback like below
table_user
| id | name |
|----|------|
| 1 | john |
| 2 | tony |
| 3 | mona |
table_feedback
| id | rate | user_id | date |
|----|------|---------|----------|
| 1 | 1 | 3 |2015-11-2 |
| 2 | 1 | 2 |2015-11-2 |
| 3 | 1 | 3 |2015-11-1 |
I wanted to show report by date from table_feedback including name and id from table_user and all user will be show if table_feedback didn't contain the user id then this will be return blank data. I have idea about inner join and here is my query. problem is that the query return 2 row only but i need 3 row including table_user id 1 with blank column rate.
Here is my query below.
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
table_feedback.date
FROM table_feedback
INNER JOIN table_user
ON table_user.id = table_feedback.user_id
WHERE table_feedback = '2015-11-2'
expected_result_table
| user_id | name | rate | date |
|-------- |------|------|----------|
| 1 |jony | |2015-11-2 |
| 2 |tony | 1 |2015-11-2 |
| 3 |mona | 1 |2015-11-2 |
The solution to this is an outer join. Anytime you find yourself thinking along the lines of "I need to see all rows from this table, regardless of a match in another table..." you should look to an outer join.
We can use an outer join to select all users, and link them to the feedbackTable in our JOIN clause. This will return null values for any columns in the table that don't match up. Try this:
SELECT u.id, u.name, t.rate, t.dateCol
FROM userTable u
LEFT JOIN feedbackTable t ON t.user_id = u.id AND t.dateCol = '2015-11-02';
Here is an SQL Fiddle example. As a side note, it is good practice not to name date columns date since that is a keyword in MySQL.
Edit based on your expected results:
To make sure the date column appears in each row, you can hardcode it into your select. If you choose to use a variable, you won't have to update the date twice each time, you can just update the declaration:
SET #reportDate = '2015-11-02';
SELECT u.id, u.name, t.rate, #reportDate
FROM userTable u
LEFT JOIN feedbackTable t ON t.user_id = u.id AND t.dateCol = #reportDate;
Here is an updated SQL Fiddle.
My guess is you need to use LEFT JOIN:
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
table_feedback.date
FROM table_user
LEFT JOIN table_feedback
ON table_user.id = table_feedback.user_id
AND table_feedback.date = '2015-11-2'
In order to include user without feedback you need to use LEFT OUTER JOIN
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
'2015-11-2'
FROM table_feedback
LEFT OUTER JOIN table_user
ON table_user.id = table_feedback.user_id
WHERE table_feedback = '2015-11-2'
You need to do three modifications to your query:
Use LEFT JOIN instead of INNER JOIN (to get all the users)
Change the table order (first the table you want to get all rows
from)
As the user 1 (john) does not have any data in the second table, you
cannot limit the rows in WHERE-clause. Do the limitation in JOIN
instead, so it applies only to the rows that are matching the JOIN.
So:
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
table_feedback.date
FROM table_user
LEFT JOIN table_feedback ON table_user.id = table_feedback.user_id and table_feedback.date = '2015-11-02'
currently i have the following query
SELECT * FROM tabs
JOIN users d ON tabs.`debit` = d.id
JOIN users c ON tabs.`credit` = c.id
as the table contains two user objects the names that get returned are the same like so:
id | amount | type | id | username | avatar | id | username | avatar
i need it to return as the following
id | amount | type | debit.id | debit.username | debit.avatar | credit.id | credit.username | credit.avatar
or something simmilar as long as the column names from the users are prefixed.
I think this is what you are looking for. Give it a try. (Assuming that id | amount | type belongs to the tabs table)
SELECT t.id,
t.amount,
t.type,
d.id as 'debit.id',
d.username as 'debit.username',
d.avatar as 'debit.avatar',
c.id as 'credit.id',
c.username as 'credit.username',
c.avatar as 'credit.avatar',
FROM tabs t
JOIN users d ON t.`debit` = d.id
JOIN users c ON t.`credit` = c.id
I have three columns I need to join which comes from 3 different tables,
Contributions table:
+-----------+---------------------+
| record_id | contributor_user_id |
+-----------+---------------------+
| 1 | 2 |
+-----------+---------------------+
| 1 | 5 |
+-----------+---------------------+
Members table:
+--------------+---------+
| username | user_id |
+--------------+---------+
| Test | 1 |
+--------------+---------+
| Test2 | 5 |
+--------------+---------+
| Test3 | 6 |
+--------------+---------+
Records table:
+---------+-----------+
| user_id | record_id |
+---------+-----------+
| 28 | 1 |
+---------+-----------+
For what I need to return is the username and user_id for displaying the record owner. Also, display the username and the user_id, but this can be multiple (more than 1+ user). I've tried this:
SELECT usr.username,
usr.user_id,
rec.record_id,
contrib.record_id,
contrib.contributor_user_id
FROM
(
records rec
INNER JOIN members usr ON rec.user_id = usr.user_id
# this returns records as NULL
LEFT OUTER JOIN contributions contrib ON rec.record_id = contrib.record_id AND contrib.contributor_user_id = usr.user_id
# this works, but I need the username to be displayed too
LEFT OUTER JOIN contributions contrib ON rec.record_id = contrib.record_id
)
WHERE rec.record_id = 1
Try nesting the join for contributing users inside of the left join to contributions.
SELECT u.username, u.user_id, r.record_id, u2.username as ContributorName, u2.user_id as ContributorId
FROM records r
INNER JOIN members u
ON r.user_id = u.user_id
LEFT JOIN contributions c
INNER JOIN members u2
ON c.contributor_user_id = u2.user_id
ON r.record_id = c.record_id
WHERE r.record_id = 1
SELECT
usr.username AS record_owner
, usr.user_id AS record_owner_id
, rec.record_id
, con.contributor_user_id AS contributor_id
, contributors.username AS contributor_name
FROM
records rec
INNER JOIN
members usr
ON rec.user_id = usr.user_id
LEFT OUTER JOIN
contributions con
ON rec.record_id = con.record_id
INNER JOIN
members contributors
ON con.contributor_user_id = contributors.user_id
WHERE
rec.record_id = 1