SQL Left Join - same results multiple times - php

I have the following tables:
users
id | name
info
id | info | user_id
(user_id from table info is foreign key => connects to id from table users)
It is possible that the user will have many entries in the info table (same user_id in many rows).
Now I want to fetch data and display it like that:
username:
... info ....
Example:
admin:
aaa
bbb
ccc
someuser:
ddd
eee
fff
So I use LEFT JOIN like that:
SELECT users.name, info.info
FROM users
LEFT JOIN info
ON users.id = info.user_id
But what I get is the following:
admin:
aaa
admin:
bbb
admin:
ccc
How can i display the username only once? I've tried using DISTINCT keyword after SELECT but it didn't help. Meanwhile i solve this problem inside the php code itself, but is there any way to fix this only inside the sql?

SELECT users.name, GROUP_CONCAT(info.info SEPARATOR 'whateveryouwant') as info
FROM users
INNER JOIN info ON (users.id = info.user_id)
GROUP BY users.name
By default group_concat uses a , as separator, but you can change that if needed.
Link:
http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html#function_group-concat

$lastname="";
$res=mysql_query($yourQuery);
while($row=mysql_fetch_assoc($res)){
if($row['name']!=$lastname){
$lastname=$row['name'];
print $lastname.':'; // first time print it
}
print $row['info'];
}

Related

Php - about SQL-query with WRONG(?) database

Easy question for you but hard solution for me.=)
I have a database - USERS. In USERS I have two tables - USERS_INFO and EVENTS.
USERS_INFO contain next fields:
user_id
user_name
...
and
EVENTS contains next:
event_id
user_id
obj_id (this element means, for examle, when user_1 will change information
event about user_2 in this table appears record like:
event_id=1
user_id=user_1
obj_id=user_2)
So, as you can see, information about user_id, obj_1 from table EVENTS I get from table USERS_INFO in field user_id.
I connected it.
The question is = how to create right query?
I need to see something like this:
user_1 user_4 some_event_like_edit (means that user_1 changed smth in user_4)
I can create query, but it works wrong. I did -
SELECT USERS_INFO.user_name, EVENTS.event FROM USERS_INFO,EVENTS WHERE USERS_INFO.user_id=EVENT.user_id
BUt I cant create query for another field obj_id!!
Result give me the fields where EVENTS.user_id=EVENTS.obj_id
What I should do??
You just need to join to user table twice, like this:
SELECT u_1.user_name as Who_Changed,u_2.user_name as Who_Got_Changed, e.event
FROM EVENTS e
INNER JOIN USERS_INFO u_1
ON (u_1.user_id=e.user_id)
INNER JOIN USERS_INFO u_2
ON (u_2.user_id=e.obj_id)

MySQL - How to get data from 3 tables

I seem to be a little stumped... I'm trying to get data from three tables, but they're not all inter-related -- one table relates to each of the other two.
Exams_taken
ID
exam_id
user_id
Exams_available
ID
exam_name
Users
ID
user_name
I want to create an output where I have the exam_id, exam_name, and user_name.
I thought I could figure out how to do this as a single query, but I'm lost. Is it possible? Or do I need to do a query on 'Exams_available' and then a loop with a second query to JOIN 'Exams_taken' and 'Users'?
Thanks,
Scott
If you need an output that contains exam_id, exam_name and user_name I can suppose that you need the Exams taken, so why not just query like this:
SELECT exam_id, E.exam_name, U.user_name FROM Exams_taken as ET
INNER JOIN Exams_available as E on ET.exam_id = E.exam_id
INNER JOIN Users as U on ET.user_id = U.user_id

mysql Search data from multiple table

I have 2 tables:
user
ID | Name | Class
Category
ID | user_id | cat_id
If user inputs data from a text field how do I search data from both tables?
You will need a basic query with joins. Something like this:
SELECT * FROM user u
LEFT JOIN category c ON c.user_id = u.id
WHERE ...
SELECT * from user, category
WHERE user.id=[text field]
or category.user_id=[text field]
or category.cat_id=[text field]
You need to join the two tables together.
Select *
from User , Category
where user.id = Category.user_id
Basicly you are linking the two together by the based upon the user_id that they both share. This way you get the information back from both tables.
Here is a link to help you understand the concept. http://www.w3schools.com/sql/sql_join.asp
Try this way
SELECT * FROM user
LEFT JOIN category ON category.user_id = user.ID
WHERE user.Name LIKE '%lorem%'
Try it
you need the time of insertion use mysql_insert_id for user_id to table2.
In the selection time use JOIN in mysql
eg
"select * from tb1,tb2 where tb1.ID=tb2.user_id and where tb1.ID='userid' "
for a specific user
Even you can do like this:
SELECT * from user
LEFT JOIN category ON user.id = category.user_id
WHERE text_field IN (user.id,category.user_id,category.cat_id)

Calculate sum from two Tables for a specific User

i have an Table with Users and an Table with events that is related to the id from the Users Table. In each Event you can make points and i want to get the total points from an specific User.
It looks like this:
Users
+----+----------+
| id | username |
+----+----------+
Events
+----------+---------+--------+
| event_id | user_id | points |
+----------+---------+--------+
// The event_id is related to an Event Table with specific data about the Event. but that not relevant.
The best could be to get the data from the user and the total points that he got in one query.
Thanks and Greetings,
Mottenmann
"..to get the data from the user and the total points that he got in one query."
You need to join both tables first so you can manipulate the data. The query below uses INNER JOIN which only includes users on the result list if it has atleast one matching record on the Events. If you want to get all users even without a single matching record on the other table, use LEFT JOIN instead.
SELECT a.ID, a.username, SUM(b.points) totalPoints
FROM Users a
INNER JOIN Events b
ON a.ID = b.user_ID
GROUP BY a.ID, a.username
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
"In each Event you can make points and i want to get the total points
from a specific User."
You could do something like this:
select sum(e.points) as points from users u
left join events e ON (u.id = e.user_id)
WHERE u.id = {$id}
where {$id} is the id of user.

PHP and MySQL many-to-many question

Still wrapping my head around SQL and PHP, but hope someone can help with this:
I have the following tables:
1.
user table
- id
- name
- email
2.
user_group table
- user_id
- group_id
3.
group table
- id
- group_name
There is a many-to-many relationship between the user table and the group table. Now what I am trying to do build a browse users page which lists all the users in the system along with the groups that they belong to, so the page would look something like this:
Name: John Doe
Groups: football, tennis, swimming
Name: Jane Doe
Groups: hockey, basketball
Name: Jim Doe
Groups: hockey, football, rugby
etc. etc.
To accomplish this, I have the following SQL:
SELECT `user`.name, `group`.name
FROM `user`, `user_group`, `group`
WHERE `user`.id = `user_group`.user_id
AND `group`.id = `user_group`.group_id
GROUP BY `user`.id, `group`.id
which returns results as follows:
1. John Doe | football
2. John Doe | tennis
3. John Doe | swimming
4. Jane Doe | hockey
5. Jane Doe | basketball
etc. etc.
As you can see, the results returned need to be manipulated in order to produce the comma separated groups shown earlier, as .
Is there a simple way to get the page to display the groups so that they are in a comma separated list for each user in MySQL? Or do I have to write PHP code to loop through the results looking for duplicate IDs and generating the comma-separated lists of groups on the page? Or am I doing something completely wrong in my approach?
Many thanks.
There are a few options (in order of my personal preference).
Don't group by user id, and iterate trough your result and create an multi dimensional array using the user id as a key.
Use GROUP_CONCAT, which isn't pretty.
Use separate queries for selecting all groups + users, and iterate to create an multi dimensional array.
It makes no sense to have group_id in your user table if it is many-to-many and you already have a connecting table.
From PHP I guess you use MySQL, so you can use GROUP_CONCAT in situations like this.
Anyway, you are querying a hierarchical structure, which can not gracefully flatted to a single table, so you will always have to do some PHP coding to get the hierchical structure back.
try with GROUP_CONCAT with INNER JOIN
SELECT user.name, GROUP_CONCAT(group.name) FROM user
INNER JOIN user_group ON user.id = user_group.user_id
INNER JOIN group ON group.id = user_group.group_id
GROUP BY user.name
You're in luck. MySQL has a very handy aggregation operator group_concat which allows you to collapse the grouped results into a single row. In your case it would go something like this:
SELECT
`user`.name,
GROUP_CONCAT(`group`.group_name)
FROM `user`
INNER JOIN `user_group` ON (`user_group`.user_id = `user`.user_id)
INNER JOIN `group` ON (`group`.group_id = `user_group`.group_id)
GROUP BY `user`.name
This will match your table structure :)
SELECT `user`.name, GROUP_CONCAT( `group`.group_name )
FROM `user`
INNER JOIN `user_group` ON ( `user_group`.user_id = `user`.id )
INNER JOIN `group` ON ( `group`.id = `user_group`.group_id )
GROUP BY `user`.name
HTH :)

Categories