Querying more than 1 table in a single query via JOIN - php

I cannot quiet get using the JOIN clause around my head, even after I have ready multiple posts on the topic.
Here is my problem:
At the moment I have 2 tables.
Users Table:
ID | Username | Password
1 | Micky | 123
2 | Mouse | 145
Questions Table:
Question ID| Question_Title | Question | Rating | Category ID | User ID |
1 | Meaning of Life? | Same as Title | 100 | 2 | 1 |
2 | Foo is love? | Same as Above | 95 | 4 | 2 |
Now I simply want to run a query which will find a match in the title and the find out which user ID corresponds to that question and then get the name of the user, as well as the Question Title, Question and Rating then print them out.
So far I have:
"SELECT Question_Title, Question, Rating FROM Questions WHERE Question_Title LIKE '%$Term%'";
This works as in it will get me the Question Title, Question and Rating from the table wherever it finds a match but how would I use JOIN so that it will also get me the Username from the Users table?
Also this is just early implementation I will in the future have a lot more tables that will require similar query so I need to understand how this works.
P.S: I know their are plenty of examples like this but I had trouble understanding them so if one of you kind souls could break it down and explain I would be grateful.

Try this
SELECT
u.username
q.Question_Title,
q.Question,
q.Rating
FROM Questions q
join Users u on u.id = q.userid
WHERE q.Question_Title LIKE '%$Term%'";

Select a.* from a join b on a.id=b.a_id join c on c.b_id = b.id
in your case something like this:
SELECT Question_Title, Question, Rating,user.* FROM Questions join User on user_id=id WHERE Question_Title LIKE '%$Term%'";

Related

MySQL custom Join row by row

So I have the following tables
**accounts**
id | iban
1 | ES80 2310 0001 1800 0001 2345
2 | ES91 2100 0418 4502 0005 1332
**acc_rel**
account_id | target_table | target_id
1 | users | 2
2 | clients | 5
**users**
id | username | password
2 | abc | cba
**clients**
id | company_name
5 | some_name
So the thing is that with acc_rel I have an account related with an user, a client, or whatever other table.
Because of reasons, not my reasons, I can't change this tables or the way they "works".
What I need to do is, retrieve the account information with the username or the company_name from the other tables, I need to do it in a single query so I can use a WHERE to filter, or ORDER BY and LIMIT. At least I think that I need it in a single query to do so.
This would be the perfect output:
account_id | account_owner
1 | abc
2 | some_name
So how can I do it? I don't know which tables I am going to do the JOIN or what column name I need, thought I can know it with PHP before doing the query.
A solution changing all the tables scheme would be appreciated too if the correct way to do this is another.
Based on #knowledge... answer I made this query and it works exactly like I need it.
SELECT AR.account_id,COALESCE(U.username, C.company_name) AS account_owner
FROM accounts AS A
INNER JOIN acc_rel AS AR ON A.id = AR.account_id
LEFT JOIN users AS U ON U.id = AR.target_id AND AR.target_table = 'users'
LEFT JOIN clients AS C ON C.id = AR.target_id AND AR.target_table = 'clients'
It is going to be a pain to maintain if I need to add new tables but well, it works the way I need.
select AR.account_id,COALESCE(U.username,C.company_name) as account_owner
from accounts A
join acc_rel AR on A.id=AR.account_id
left join users U on U.id=AR.traget_id and AR.target_table='user'
left join clients C on C.id=AR.traget_id and AR.target_table='clients'

Applying filter using SQL Join

My website is a Q&A site like stackoverflow.com. When a user creates a question, he has the ability to tags it. Later, when he need to find all questions which belongs to a category, he can use the filter box which accepts tag names. Based on user entries, i will just refresh the job list.
My table design is like below
Table: Questions
id | QuestionTitle |Other details|
----------------------------------|-------------|
1 | Why is earth round? |
2 | How much is moon's diameter? |
Table: Tags
id | tagname
----------------
1 | planets
2 | earth
3 | moon
Table: AttachedTags
id | question_id | tag_id
-------------------------
1 | 1 |2
2 | 1 |1
3 | 2 |3
In the PHP/Controller i will get tag id's as user input's in the filter box.
What is the best method to fetch all those questions under a particular tag?
I have used the following query, but it is retrieving a job two times, because a job can have more than one category.
SELECT
Questions.id,
Questions.jobtitle,
AttachedTags.tag_id
FROM
Questions INNER JOIN
AttachedTags ON Questions.id = AttachedTags.question_id
WHERE
AttachedTags.tag_id IN (1,2)
Isn't it enough to add a distinct to filter out duplications and remove tag_id from the select?
SELECT DISTINCT
Questions.id,
Questions.jobtitle
FROM
Questions INNER JOIN
AttachedTags ON Questions.id = AttachedTags.question_id
WHERE
AttachedTags.tag_id IN (1,2)

Selecting one record from two tables

I'm stuck with one SQL query. I have two tables:
users
________________________
| id | company | worker|
-------------------------
| 1 | my comp | John |
tasks
_________________________
| id | name | company |
-------------------------
| 1 | exm | my comp |
My problem is that I want to show tasks of these companies which worker is John. I'm in trouble in that for hours but I don't know how to do it. Is there any SQL query to do that?
You can do a simple join using company column from both tables and use where clause to filter results for John
SELECT t.*
FROM users u
JOIN tasks t USING(company)
WHERE u.worker ='John'
You want use the inner join tag. Just a modification on the other queries mentioned for better clarity.
SELECT task.name,user.worker,user.company
FROM tasks as task INNER JOIN users as user
ON user.company=task.company
WHERE user.worker='John';
You can do a simple join like...
$qry = "SELECT u.id,u.company,u.worker,t.id,t.name,t.company FROM users as u JOIN tasks as t ON u.company = t.company WHERE u.worker = 'John'";

Fairly complex SQL statement using inner join (I presume)

I'm having trouble figuring out how to write an SQL query to return results from the following table structure.
The first thing I do is get a list of clients that have a status equal to 1 by:
SELECT * FROM clients WHERE status=1
Then I need to get all user email addresses that belong to a client. My plan was to loop through the results of the query above and running multiple queries for each client. As you can see from the table 'client_user_list' a single user can belong to multiple clients.
I tried doing something like this:
SELECT emailaddress
FROM users
INNER JOIN client_user_list ON users.user_id = client_user_list.user_id
WHERE users.client_id = 1
But it failed. As you can see I'm a total novice when it comes to this stuff. Any help would be appreciated, or feel free to point me to an appropriate resource to learn more. I've looked, but I haven't found anything that covers something complex like this.
Additional info: Using foreign keys there are relationships between clients <-> client_user_list and client_user_list <-> users
clients:
|---------------------------------------|
| client_id | client_name | status |
|---------------------------------------|
| 1 | John Doe | 1 |
| 2 | James Doe | 0 |
|---------------------------------------|
client_user_list:
|----------------------|
| client_id | user_id |
|----------------------|
| 1 | 5 |
| 2 | 6 |
| 1 | 6 |
|----------------------|
users:
|---------------------------------------|
| user_id | emailaddress |
|---------------------------------------|
| 5 | notan#email.com |
| 6 | afake#email.com |
|---------------------------------------|
Thanks so much in advance.
I'm not sure if this is your only problem, since you didn't specify what the exact problem is, but the WHERE-clause of your query contains an error. You query should be changed into this:
SELECT DISTINCT emailaddress
FROM users
INNER JOIN client_user_list ON users.user_id = client_user_list.user_id
WHERE client_user_list.client_id = 1
The users table does not have a field called client_id, the client_user_list table does.
You can get the clients with status = 1 and their users with only one query, by joining all three tables:
select clients.client_id, clients.client_name, users.user_id, users.emailaddress
from clients
inner join client_user_list on client_user_list.client_id = clients.client_id
inner join users on client_user_list.user_id = users.user_id
where clients.status = 1
order by clients.client_id, users.user_id
The following command should resolve this issue
I hope it is userful.
select distinct use.emailaddress
from clients cli
inner join client_user_list cul on (cli.client_id=cul.client_id)
inner join users use on (cul.user_id = use.user_id)
where cli.status = 1

mySQL JOIN query beat down

Alright, I'm not the best with JOIN's and after all these years of working with mySQL you think I would be by now at the least minimally decent. Guess I've never really worked on anything superbly complex til now worth needing to join a table. So here I am, confused ever so slightly in need of a helpful example to get me on a roll, something that's pertinent to my actual data that I can make heads or tales of cause all the reading I'm doing online else where just gives me headaches for the moment. I think I might be stuck on the mythology of JOIN's being a hard thing to do, they don't seem like it but when ever I've tried I fail. So anyway I am working with PHP as my server side coding, and I believe MySQL 5.
So heres the construct to an extent.
I have table information and table connections.
Connections has: member_id, connection_id, active
Information has: firstname, lastname, gender, member_id
I should say the tables contain more data per table, but as I understand it I need write a query that I can use the member_id as the connector/foreign key. Where I can use both sides of the information. I need to know if active is 1, and then I need to know all of the columns above mentioned for information.
I tried
SELECT member_id,
connection_id,
active,
firstname,
lastname,
gender,
member_id
FROM connections, information
WHERE connection.member_id = information.member_id AND
connection.active = 1
and I've tried
SELECT * FROM connections, information
WHERE connection.member_id = information.member_id AND
connection.active = 1
With the first one I get member_id is ambitious which is understandable to a point i think cause of the matching columns between the two tables. Then the second query doesn't server me well as it only results with one person.
My Ultimate goal is to find all the connections for a specific member_id in the connections table, while gathering all the information about those connections from the information table using the connection_id as its the same thing as the member_id in the in the information table.
So in laymans terms if I am not making sense lets say I wanted to list out all my friends in from the DB. My connection table lets me know which people I am connected to where member_id is my id and connection_id is my friends member_id on another table. Hopefully that makes more sense. And this is where I am having trouble with my query and trying to write it correctly. If I could get a working sane sample of that I think I might be able to make better sense of JOIN's doesnt help that I also can't figure out what type of JOIN is best suited for my needs either I suppose.
EDIT....
Ok as per request from comment below. Sample data expected output from tables that look similar to this:
Connections Table
member_id, connection_id, active
1 | 2 | 1
1 | 3 | 1
1 | 4 | 1
1 | 5 | 1
2 | 1 | 1
2 | 5 | 1
3 | 1 | 1
Information Table
member_id, firstname, lastname, gender, ...other unimportant rows for this query
1 | Chris | Something | m | ....
2 | Tony | Something | m | ....
3 | Brandon | Something | m | ....
4 | Cassie | Something | f | ....
5 | Jeff | Something | m | ....
6 | John | Something | m | ....
now from the connections table I need to gather all the connection_id's associated with my member_id where active is 1 then from the information table gather everyone firstname, lastname, gender.. Now I know I can do this 2 step where I pool all the connection_id's from connections then run them through a loop of some sort and one by one get the resulting id's from the first query but to me that seems a bit obscure and process intensive which I want to avoid, which brings me here.. Currently from my original query posted to the many shared thus far trying to help my results are to the effect of
1 | Chris | Something | m | 2
1 | Chris | Something | m | 3
1 | Chris | Something | m | 4
1 | Chris | Something | m | 5
what I'd like to see returned is something like
2 | Tony | Something | m
3 | Brandon | Something | m
4 | Cassie | Something | f
5 | Jeff | Something | m
After looking at this I suppose I would also need to know the friendID column that matches my member_id as well but thats something to figure out after this initial hurdle
The error is in your WHERE Clause because instead of Connections you wrote it Connection which then the server generates the error.
...
WHERE connection.member_id = information.member_id AND
connection.active = 1
try this:
SELECT a.Member_ID,
a.FirstName,
a.LastName, a.gender,
b.Connection_ID
FROM Information a INNER JOIN Connections b
on a.Member_ID = b.Member_ID
WHERE b.`Active` = 1
UPDATE
if that's the case then you will most likely have a SELF JOIN
SELECT DISTINCT b.Connection_ID,
c.*
FROM Information a INNER JOIN Connections b ON
a.Member_ID = b.Member_ID
INNER JOIN Information c ON
b.Connection_ID = c.Member_ID
WHERE b.`Active` = 1
AND a.Member_ID = 'ID HERE' -- If you want to get for specific member
The error in the first is "ambiguous" not ambitious. Ambiguous means that the SQL engine doesn't know which column you are talking about, because you have two columns with the same name (different tables but still).
You can fix that by specifying the table name along with the column name where you list the columns for select.
For example
SELECT connections.member_id, connection_id, active, firstname, lastname, gender, information.member_id FROM connections, information WHERE connections.member_id = information.member_id AND connections.active = 1
The problem with returning only one suggests that there is only one record that matches your query but it's hard to guess.
Try changing to:
SELECT * FROM connections c JOIN information i ON i.member_id = c.member_id WHERE c.active = 1
Try this:
SELECT *
FROM information
LEFT OUTER JOIN connections
ON information.member_id = connections.member_id
WHERE connections.active = 1;
You're joining on the wrong tables. You said:
where member_id is my id and connection_id is my friends member_id on another table
Then, what you have to match is connections.connection_id with information.member_id. The simplest solution is:
select c.member_id, c.connection_id, c.active from connections c
join information i on c.connection_id = i.member_id
where c.active = 1 and c.member_id = #yourId
That's all :)

Categories