How to merge the rows of a second table into 1 field - mysql

I've been trying to produce a query that will search table1, and then CONCAT the all the values of table2.column1 where table1.id = table2.owner
People
name | id
-------------
tim | 1
jill | 2
john | 3
Dogs
name | owner
--------------
a | 1
b | 1
c | 2
d | 2
Using the following table i need a query that would output
name | dogs
-----------
tim | a, b
jill | c, d
john | NULL (or a blank text or just so long as the name john still shows)
I have spent a few hours and really cant do it. Some form of mash between OUTER JOIN, and group_concat(), i think. But i didnt really get close to my answer.
Thank you for all help!

You will want to use GROUP_CONCAT and a GROUP BY
SELECT p.name, GROUP_CONCAT(d.name)
FROM people p
LEFT JOIN dogs d
ON p.id = d.owner
GROUP BY p.name
see SQL Fiddle with Demo

I guess you looking for GROUP_CONCAT in MySQL.
SELECT a.name, GROUP_CONCAT(b.name) dogsName
FROM People a
LEFT JOIN Dogs b
ON a.id = b.owner
GROUP BY a.name
SQLFiddle Demo

Related

How to not equal multiple table mysql

Table_Teacher
id | name
-----------------
1 | Kevin
2 | Alex
3 | jax
4 | Albert
Table_Supervisor
id | id_teacher
-----------------
1 | 1
2 | 3
I want to display 2 data (Alex & Albert) in table_teacher
with queries
SELECT A.name FROM table_teacher A,tbl_supervisor B WHERE B.id_teacher != A.id;
why is this not working ?
There are various ways.
A simple one is to use a subquery to get all teachers that are not contained in the subquery of supervisor
SELECT A.name FROM table_teacher a where a.id not in
(select b.id_teacher from table_supervisor b WHERE b.id_teacher = a.id);
You could use LEFT JOIN, which might perform better than subqueries.
select t.name
from Teacher t
left join Supervisor s on t.id=s.id_teacher
where s.id_teacher is null;
Above query will get only the values which are on Teacher table but not on Supervisor table
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=98ae9aa420456e69bae05f00ec34eb43

Group data from 3 SQL tables

I want to match some sql entries and group them like the fallowing:
workers_table
ID | worker
------+--------------
1 | Smith
2 | John
3 | Luke
workers_tools_usage
worker_id | tool_id
-------------+----------
1 | 1
1 | 2
1 | 3
3 | 1
tools_table
tool_id | name
-------------+----------
1 | hammer
2 | wrenches
3 | drill
4 | screwdriver
And my desired match should look like this:
worker | tool
-------------+----------
Smith | hammer,wrenches,drill
Luke | hammer
Is this possible using Mysql ? Tried some UNION but no luck.
I would write the query as:
select w.id, w.worker, group_concat(t.tool)
from worker w join
workers_tools_usage wtu
on wtu.worker_id = w.id join
tools t
on t.tool_id = wtu.tool_id
group by w.worker w.id;
I am answering for the following reasons
No outer joins are necessary as the question is asked.
To show an example of meaningful table aliases, which are abbreviations for the table names.
To provide an answer with all the columns qualified by the tables they belong in.
Try using group_concat() - I assume your tool table worker_id as tool_id
select worker,group_concat(tool)
from workers_tools_usage w1 left join worker w2 on w1.worker_id=w2.id
left join tools_table t on w1.tool_id=t.tool_id
group by worker
select w2.worker,group_concat(t.tool separator ',') tool
from workers_tools_usage w1
left join worker w2
on w1.worker_id=w2.id
inner join tools_table t
on w1.tool_id=t.tool_id
group by w2.worker

Distinct values of grouped attributes in SQL

I have two tables:
Table1 name object Table2 name_old name_corr
------|-----| ---------|-----------
John | A | John | John
Ben | B | Ben | Ben
Jon | B | Jon | John
Be n | B | Be n | Ben
Peter | B | Peter | Peter
Petera| C | Petera | Peter
In my Example I have three persons, in Table1 there are some typing errors, so Table2 assigns every name to the correct name.
Now I want for every Person (John, Ben, Peter) their distinct objects.
This would be the outcome:
John A
B
Ben B
Peter B
C
This was my try, but I get an error:
Select b.name_corr, distinct(a.object) from Table1 as a join Table2 as b on (a.name=b.name_old) group by b.name_corr
Without the grouping, meaning if I select a specific name via 'where' my query works.
distinct isn't a function. It is a qualifier on select:
Select distinct b.name_corr, a.object
from Table1 a join
Table2 b
on a.name = b.name_old;
use group_concat:
Select b.name_corr, group_concat(distinct a.object) from Table1 as a join Table2 as b on (a.name=b.name_old) group by b.name_corr;
I figured out a solution for my problem. -> Double 'group by'. So simple..
Thanks for the help anyway.

MySQL Left Join Many to One Row

To simplify my problem: Let's say I have 3 tables.
Rooms People Things
-------- -------- --------
id| name id | name | fk_rooms id | name | fk_rooms
----------- --------------------- ---------------------
1 | kitchen 1 | John | 1 1 | TV | 2
2 | bedroom 2 | Mary | 2 2 | bed | 2
3 | Andy | 1 3 | sink | 1
4 | Laura| 1
Now I'm doing something like:
SELECT r.name AS room_name, p.name AS name, t.name AS thing FROM Rooms r
LEFT JOIN People p ON p.fk_rooms = r.id
LEFT JOIN Things t ON t.fk_rooms = r.id
which in my case works perfectly except for a few that have many to one relationship with the "Rooms" table. So instead of new rows in the result set holding the different names for "People" and "Things" in relation to the "Rooms" table, I would like to receive only two rows:
1. kitchen, John, Andy, Laura, sink
2. bedroom, Mary, TV, bed
A GROUP BY on r.id will only select one row from each table. Any help is highly appreciated!
Here it is what you're looking for:
SELECT r.name AS room_name,
GROUP_CONCAT(p.name separator ',') AS people_name,
GROUP_CONCAT(t.name separator ',') AS things
FROM Rooms r
LEFT JOIN People p ON p.fk_rooms = r.id
LEFT JOIN Things t ON t.fk_rooms = r.id
GROUP BY r.id
Yes, you need the group by clause, and you need to use the GROUP_CONCAT function. You should group your results by People.fk_rooms and Thing.fk_rooms.
Maybe you could use two different queries: The first will result the join of Rooms and People, grouped by fk_rooms, having selected three columns, they are being RoomsID, RoomName, People, while the second will result the join of Rooms and Thing, grouped by fk_rooms, having selected three columns, they are being RoomID, RoomName, Things. In your query you name these selections as t1 and t2 and join t1 and t2 by RoomsID, select t1.RoomName, t1.People, t2.Things.
Good luck.

How to do this in SQL query?

Table: A Table: B Table: C
------------ ---------------- -------------
P_id | G_id P_id | Name G_id | Title
------------ ---------------- -------------
1 | 1 1 | john 1 | php
2 | 1 2 | jack 2 | sql
3 | 2 3 | sam
Now I am quering like:
Select B.name, C.title
from B inner join A on...
inner join c on...
If we input john here then it will display like this:
john php.
But I want to display it like:
john jack php.
Because G_id of john and jack is same.
How can i do this?
Pseudo code (similar to mysql):
SELECT B.name, C.title
FROM B
INNER JOIN A ON A.P_id = B.P_id
INNER JOIN C ON A.G_id = C.G_id
WHERE A.G_id = (
SELECT A.G_id
FROM B
INNER JOIN A ON A.P_id = B.P_id
WHERE B.Name LIKE '%John%' LIMIT 1
);
EDIT:
This will make your results searchable by name, use GROUP_CONCAT and GROUP BY as suggested by Everton Agner to correctly format the results.
You need an Aggregation Funcion to work with this kind of grouping. I'm not fluent at MySQL, but try something pretty much like this, using the group_concat() function:
select
group_concat(b.Name),
c.Title
from
A a
join B b on b.P_id = a.P_id
join C c on c.G_id = a.G_id
group by
c.Title
Hopefully it'll show you "john,jack"
Check the docs about Aggregation functions here: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
-- EDIT
Just tested it, it gave me the following output:
+----------------------+-------+
| group_concat(b.Name) | Title |
+----------------------+-------+
| john,jack | php |
| sam | sql |
+----------------------+-------+
I hope is that what you want :)
-- EDIT (the last one)
Now I think I understood what you want, just add having group_concat(b.Name) like '%john%' and it'll give you only the groups that john is included... The better choice would be an array contains function, but I haven't found it.
+----------------------+-------+
| group_concat(b.Name) | Title |
+----------------------+-------+
| john,jack | php |
+----------------------+-------+