How to do this in SQL query? - mysql

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 |
+----------------------+-------+

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 Filtering rows from three tables

Let's say i've got this database:
book
| idBook | name |
|--------|----------|
| 1 |Book#1 |
category
| idCateg| category |
|--------|----------|
| 1 |Adventures|
| 2 |Science F.|
book_categ
| id | idBook | idCateg | DATA |
|--------|--------|----------|--------|
| 1 | 1 | 1 | (null) |
| 2 | 1 | 2 | (null) |
I'm trying to select only the books which are in category 1 AND category 2
This is what I've got so far:
SELECT book.* FROM book,book_categ
WHERE book_categ.idCateg = 1 AND book_categ.idCateg = 2
Obviously, this giving 0 results becouse each row has only one idCateg it does work width OR but the results are not what I need. I've also tried to use a join, but I just can't get the results I expect.
Here it's the SQLFiddle of my current project, the data at the begining is just a sample.
SQLFiddle
Any help will be really appreciated.
You could double join with a constraint on the category id:
SELECT a.* FROM book AS a
INNER JOIN book_categ AS b ON a.idBook = b.idBook AND b.idCateg = 1
INNER JOIN book_categ AS c ON a.idBook = c.idBook AND c.idCateg = 2
You could use a subquery:
SELECT a.* FROM book AS a
WHERE
(SELECT COUNT(DISTINCT idCateg) FROM book_categ AS b
WHERE b.idBook = a.idBook AND b.idCateg IN (1,2)) = 2
If you are on MySQL as your fiddle implies, you should prefer the join variant, since most joins are much faster in MySQL than subqueries.
edit
This one should also work:
SELECT a.* FROM book a
INNER JOIN book_categ AS b ON a.idBook = b.idCateg
WHERE b.idCateg IN (5, 6)
GROUP BY idBook
HAVING COUNT(DISTINCT b.idCateg) = 2
and should be faster than the two above, although you have to change the last number according to the number of category ids you are requesting.

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

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