Mysql query to join two tables using many to many relation - mysql

I have three tables called Notes another table called Tags and third as a Join table called NoteTagsJoin, Join table holds two foreign keys primary Note id and Primary Tag id. I use this query to get all Notes with tagId:
SELECT * FROM notes INNER JOIN note_tag_join ON notes.entryId = note_tag_join.noteId WHERE note_tag_join.tagId =:tagId
And this query to get all Tags:
SELECT * FROM tags INNER JOIN note_tag_join ON tags.tagId = note_tag_join.tagId WHERE note_tag_join.noteId =:noteId
How can I get Note and all its tags using just Note id with one query?

Are you looking for two joins?
SELECT n.*, t.*
FROM notes n INNER JOIN
note_tag_join nt
ON n.entryId = nt.noteId INNER JOIN
tag t
ON t.tagId = nt.tagId
WHERE n..entryId = :noteId

SELECT * FROM table_name
LEFT JOIN table_name2 ON table_name.id = table_name2.id
LEFT JOIN table_name3 ON table_name2.id = table_name3.id
WHERE table_name.id = id;
Change the "id" with the appropriate id's that you're using. It's important that the id's in the JOINs are coherent, else there will be no link between them.

If you want to select fields of the 3 tables, do this:
SELECT (fields that you want to show) FROM tableA
INNER JOIN tableB ON tableA.commonField = tableB.commonField
INNER JOIN tableC ON tableB.commonField = tableC.commonField

Related

How to relate a table more than one time in SQL?

I want to relate two tables and a relation table. Tables are: Person with it's primary key named id_person, Activity with it's primary key named id_activity and a table that relates the previous two tables: Activity_Person that contain as primary and foreign keys id_activity and id_person.
To relate this tables using the old JOIN format this would work:
select * from activity, person, activity_person
where activity.id_activity = activity_person.id_activity and person.id_person = activity_person.id_person;
This would show the activities that each person has taken part on.
But now I'm learning about JOINs and I don't know what's the correct format to relate a table that appears twice (Activity_Person).
I have tried this:
select * from
person inner join activity_person on person.id_person = activity_person.id_person,
activity inner join activity_person on activity.id_activity = activity_person.id_activity;
But I get the following error:
Not unique table/alias: 'activity_person'
What's the correct format?
You don't need activity_person twice here. Just do
select *
from person
inner join activity_person on person.id_person = activity_person.id_person
inner join activity on activity.id_activity = activity_person.id_activity;
I think you just want two joins:
select *
from person p inner join
activity_person ap
on p.id_person = ap.id_person inner join
activity a
on a.id_activity = ap.id_activity;
I'm not sure why you are trying to repeat activity_person in your query.
Also note that table aliases make the query easier to write and to read.
Your syntax is incorrect.
select * from activity, person, activity_person
where activity.id_activity = activity_person.id_activity
and person.id_person = activity_person.id_person;
Is equivalent to :
select *
from person
inner join activity_person
on person.id_person = activity_person.id_person -- <- remove the comma there
inner join activity
on activity.id_activity = activity_person.id_activity;
Basically, the syntax is like this :
SELECT <the fields to select>
FROM <table name>
JOIN <table to join>
ON <joining condition>
-- if you want to add another table :
JOIN <new table to join>
ON <joining condition>

Join statement with multiple conditions

Ok I have two mysql table one called books and the other reading_tracking.
I have written the join query below:$query = "SELECT * FROM books inner join reading_tracking on book_num = book_id;
My dilemma is that i don't want all the from books i want a query which in theory would look something like this:
"SELECT * FROM books
where reading_status = 1 inner
join SELECT * FROM reading_tracking
on book_num = book_id";
If i try this as suggested:
SELECT * FROM books b
INNER JOIN reading_tracking rt
ON b.book_id = rt.book_num
WHERE rt.reading_status = 1;
The thing is in my program not all books in books table are in reading_tracking, user have to make an additional step, so i don't want books that are similar in both tables i want all the books from books where reading_status = 1; but want all the books from reading_tracking.
Your syntax should have the SELECT [x] FROM followed by the INNER JOIN, and then you need an ON to denote which field is synonymous between the two tables. In your example, I'm assuming you have a column book_id in books, and a column book_num in reading_tracking.
The WHERE clause should come after the ON, and additionally should specify which of the two tables you want to look for the column in.
This can be seen in the following:
SELECT * FROM books b
INNER JOIN reading_tracking rt
ON b.book_id = rt.book_num
WHERE rt.reading_status = 1;
This will search books for any row that has a reading_status of 1 in the reading_tracking table.
I assume column book_num is from books table, column book_id is from reading_tracking table. First join the 2 tables then use WHERE to filter the condition:
SELECT * FROM books b
INNER JOIN reading_tracking r
ON b.book_num = r.book_id
WHERE b.reading_status = 1;
You can use a subquery before doing the JOIN as shown below:
SELECT *
FROM (SELECT * FROM books WHERE reading_status=1) A
INNER JOIN reading_tracking B on B.book_num=A.book_id;
See Using MySQL Alias To Make The Queries More Readable

How to match this using SQL?

I am using the 3 following tables:
First table
id
response
Second table
responseid
patientid
Third table
patientid
The relationship between first and second table is on id and responceid.
The relationship between third and second is on patientid.
Now I need to retrieve values from these tables like all values from first and third tables with the help of matching with patientid from second and 3rd table.
How can I do this?
Basically if all of the columns that defines their relationship are not nullable, then INNER JOIN will suffice. But if they are nullable and you still want to display all records from firstTB, you need to use LEFT JOIN instead of INNER JOIN.
SELECT a.*, b.*, c.*
FROM firstTB a
INNER JOIN secondTB b
ON a.ID = b.responceID
INNER JOIN thirdTB c
ON b.patientID = c.patientID
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
You're probably looking for INNER JOIN or JOIN in general:
SELECT
response.id,
response.responce,
patient.patientid
FROM
`response_table` as `response`
INNER JOIN
`relation_table` as `relation`
ON
relation.responceid = response.id
INNER JOIN
`patient_table` as `patient`
ON
relation.patientid = patient.patientid
try
SELECT first.*
, third.*
FROM first
INNER JOIN second ON ( second.responseid = first.id )
INNER JOIN third ON ( third.patientid = second.patientid )
;
honestly, and no insult intended, if you have difficulties in coming up with queries like this one on your own, consider some training on db basics and db development, the sooner the better (just hoping i haven't blundered myself ... ;-)).

mySQL join 3 columns from each of two tables

I am trying to join data from two tables where the userid from table 1 is in table 2.
I have tried multiple variations with no luck and read a dozen posts here on SO on this topic.
The data in table one has an id, username, rolerequest, and appuserid. I am selecting the last three items and trying to join 3 items from table 2 when the appserid from table 1 is equal to the userid from table 2.
here is my latest attempt;
SELECT username, rolerequest, appuserid
FROM userrolespending
LEFT JOIN my_aspnet_membership.email,my_aspnet_membership.creationdate,my_aspnet_membership.lastlogindate
where my_aspnet_membership.userid = userrolespending.appuserid;
In this case, you don't need to use LEFT JOIN because you only want to return userid that are present from both tables. INNER JOIN returns records that the ID or the linking columns are both present on all tables.
SELECT a.*, b.* -- <== select the columns you want to appear
FROM userrolespending a
INNER JOIN my_aspnet_membership b
ON a.appserid = b.userID
or to be exact,
SELECT a.username, a.rolerequest, a.appuserid,
b.email,b.creationdate, b.lastlogindate
FROM userrolespending a
INNER JOIN my_aspnet_membership b
ON a.appserid = b.userID
i think this is what you need :
SELECT username, rolerequest, appuserid
FROM userrolespending
LEFT JOIN my_aspnet_membership
on my_aspnet_membership.userid = userrolespending.appuserid;

How do you do a mysql join where the join may come from one or another table

This is the query that I am using to match up a members name to an id.
SELECT eve_member_list.`characterID` ,eve_member_list.`name`
FROM `eve_mining_op_members`
INNER JOIN eve_member_list ON eve_mining_op_members.characterID = eve_member_list.characterID
WHERE op_id = '20110821105414-741653460';
My issue is that I have two different member lists, one lists are members that belong to our group and the second list is a list of members that do not belong to our group.
How do i write this query so that if a member is not found in the eve_member_list table it will look in the eve_nonmember_member_list table to match the eve_mining_op_members.characterID to the charName
I apologize in advance if the question is hard to read as I am not quite sure how to properly ask what it is that I am looking for.
Change your INNER JOIN to a LEFT JOIN and join with both the tables. Use IFNULL to select the name if it appears in the first table, but if it is NULL (because no match was found) then it will use the value found from the second table.
SELECT
characterID,
IFNULL(eve_member_list.name, eve_nonmember_member_list.charName) AS name
FROM eve_mining_op_members
LEFT JOIN eve_member_list USING (characterID)
LEFT JOIN eve_nonmember_member_list USING (characterID)
WHERE op_id = '20110821105414-741653460';
If you have control of the database design you should also consider if it is possible to redesign your database so that both members and non-members are stored in the same table. You could for example use a boolean to specify whether or not they are members. Or you could create a person table and have information that is only relevant to members stored in a separate memberinfo table with an nullable foreign key from the person table to the memberinfo table. This will make queries relating to both members and non-members easier to write and perform better.
You could try a left join on both tables, and then selecting the non-null results from the resulting query -
select * from
(select * from
eve_mining_op_members as x
left join eve_member_list as y1 on x.characterID = y1.characterID
left join eve_member_list2 as y2 on x.characterID = y2.characterID) as t
where t.name is not null
Or, you could try the same thing with a union and using inner join (assuming joined tables are the same):
select * from
(select * from eve_mining_op_members as x
inner join eve_member_list as y1 on x.characterID = y1.characterID
UNION
select * from eve_mining_op_members as x
inner join eve_member_list2 as y2 on x.characterID = y2.characterID) as t
You can throw in your op_id condition where you see fit (sorry, I didn't really understand where it came from). Good luck!
You have several options but by
using a UNION between the eve_member_list and eve_nonmember_member_list table
and JOIN the results of this UNION with your original eve_mining_op_members table
you will get your required results.
SQL Statement
SELECT lst.`characterID`
, lst.`name`
FROM `eve_mining_op_members` AS m
INNER JOIN (
SELECT characterID
, name
FROM eve_member_list
UNION ALL
SELECT characterID
, name
FROM eve_nonmember_member_list
) AS lst ON lst.characterID = m.characterID
WHERE op_id = '20110821105414-741653460';