Select Multiple rows in single column separated by New Line - mysql

I have a table with values look like this.
Id Name Fruit
------------
1 Jon Apple
------------
2 Jon Orange
------------
3 Jon Grape
------------
4 Mike Apple
------------
5 Mike Orange
-------------
How to distinct the column into something like this in mysql?
Name Fruit
----------
Jon Apple
Orange
Grape
-----------
Mike Apple
Orange
-----------

This should do
SELECT name, GROUP_CONCAT(fruit SEPARATOR '\n') FROM your_table GROUP BY name
Demo in db<>fiddle
Update to add numbering:
SELECT name ,
GROUP_CONCAT(CONCAT (rn,')',fruit) SEPARATOR '\n')
FROM (
SELECT *
,ROW_NUMBER() OVER (PARTITION BY name) AS rn
FROM your_table
) SQ
GROUP BY name
Demo with numbering in db<>fiddle

Another option is also using joins to achieve this requirement.
select
case when t1.id = t2.id then t1.name else '' end
, t3.fruits
from
(select min(id) id, name from testA
group by name) t1
left join
testA t2 on t2.name = t1.name
left join
testA t3 on t3.id = t2.id
order by t2.id asc
see dbfiddle.

Related

Getting values from 2 tables with different conditions for both tables

Table 1
ID
FirstName
LastNmae
city
Group
code
11
john
smith
abc
E
P
21
don
davis
def
E
P
3
vee
miller
ghi
Q
P
6
vee
miller
ghi
Q
P
Table 2
ID
FirstName
LastNmae
city
Status
EmpName
Phone
11
john
smith
abc
U
Company 1
123
21
don
davis
def
P
Company 2
456
3
vee
miller
ghi
C
Company 3
789
4
jim
jones
xyz
P
comapany4
001
I have 2 tables mentioned above. I need an output from both table under these conditions
For table 1 condition is:
Group='E' AND code='P'
For table 2 condition is : Status = 'U' OR Status = 'P'
For output required columns are:
ID, FirstName, LastName, City, EmpName, Phone
I cannot use UNION because number of columns mismatch.
Desired Output:
ID
FirstName
LastNmae
city
EmpName
Phone
11
john
smith
abc
Company 1
123
21
don
davis
def
Company 2
456
4
jim
jones
xyz
comapany4
001
How can i get desired output. With UNION i can't get "EmpName" and "Phone" column. Is there anyway to use JOIN to get desired output.
I think you still need UNION. Try this query:
SELECT ID, FirstName, LastName, city, EmpName, Phone
FROM table2
WHERE Status IN ('U', 'P')
UNION
SELECT t1.ID, t1.FirstName, t1.LastName, t2.city, t2.EmpName, t2.Phone
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t1.ID = t2.ID
WHERE t1.Group = 'E' AND t1.code = 'P'
;
First, your results are all coming from table2, so this returns the results specified in the question:
select t2.ID, t2.FirstName, t2.LastName, t2.city, t2.EmpName, t2.Phone
from table2 t2
where t2.status in ('U', 'P');
I think you also want a matching condition on table1 (which is not needed for your example). Based on your description:
select t2.ID, t2.FirstName, t2.LastName, t2.city, t2.EmpName, t2.Phone
from table2 t2
where t2.status in ('U', 'P') or
exists (select 1
from table1 t1
where t1.id = t2.id and
t1.Group = 'E' and t1.code = 'P'
);

can not get the nth result in mysql

I need help getting the nth number of a result in MySQL.
I have three tables with the following fields:
table1: product_id, name, description
table2: category_id, name, description
table3: product_id, category_id
I'm trying to get this result:
name | description - product_category -category2 - category3
___________________________________________________________________
NAME 1 | Description 1 | Cat1 | Cat2 | Cat5
NAME 2 | Description 2 | Cat7 | Cat9 | Cat11
The query I'm trying to use is as follows:
SELECT
t1.name AS product_name,
t1.description AS product_description,
(SELECT t2.name from table2 order by name ASC LIMIT 1
OFFSET 1) AS product_category,
(SELECT t2.name from table2 order by name ASC LIMIT 1
OFFSET 2) AS product_category2,
(SELECT t2.name from table2 order by name ASC LIMIT 1
OFFSET 3) AS product_category3
FROM table1 t1 INNER JOIN
table3 t3
ON t3.product_id = t1.product_id INNER JOIN
table2 t2
ON t2.category_id = t3.category_id
;
And sadly I get this result:
name - description - category
NAME 1 - Description 1 - Category 1
NAME 2 - Description 2 - Category 2
Try using LEFT JOIN instead of INNER JOIN.
Example:
SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name = table2

Using a nested query to get details of two tables

TABLE 1 TABLE 2
id name mob id course mark
1 joe 0000 1 English 77
2 john 0000 2 maths 89
I need to show the name of the person from table 1 who has the MAX(grade) in table 2 using a nested query.
SELECT t1.name
FROM t1
WHERE t1.id = t2.id = (
SELECT id
FROM t2
WHERE mark =
(
SELECT MAX(mark)
FROM t2
)
);
Well, this satisfies the brief ;-):
SELECT a.*
FROM table_a a
JOIN (SELECT * FROM table_b) b
ON b.id = a.id
ORDER
BY mark DESC
LIMIT 1;

How to union one column only from multiple tables?

I am finding it hard to frame the question so I will show what I am trying to do.
Table1 (ID, Name, Score)
1 Jane 10
2 Jack 15
3 Jill 12
4 Jane 10
Table2 (ID, Name, Score)
1 John 11
2 Jill 14
3 Jack 16
4 Jake 15
The result I would like is
Result (Name, Table1.Score, Table2.Score)
Jane 20 NULL
Jack 15 16
Jill 12 14
John NULL 11
Jake NULL 15
Can name become the primary key? Note that Jane occurs twice in table 1(could occur in table 2 as well) and I want to sum the score and make the name unique in that given table.
Here's one way to do it with UNION and SUM:
SELECT T.Name, Sum(T.Score), Sum(T2.Score) Score2
FROM (SELECT Name, SUM(Score) score FROM Table1 GROUP BY Name) t
LEFT JOIN (SELECT Name, SUM(Score) score FROM Table2 GROUP BY Name) t2
ON t.Name = t2.Name
GROUP BY T.Name
UNION
SELECT T.Name, Sum(T2.Score), Sum(T.Score) Score2
FROM (SELECT Name, SUM(Score) score FROM Table2 GROUP BY Name) t
LEFT JOIN (SELECT Name, SUM(Score) score FROM Table1 GROUP BY Name) t2
ON t.Name = t2.Name
GROUP BY T.Name
And here is the SQL Fiddle.
Good luck.
try this
select t1.name , sum(t1.score) as score1 ,sum(t2.score2) as score2 from Table1 as t1
left JOIN
(select name , score as score2 from Table2 )t2
on t1.name = t2.name
group by name
union all
select t2.name , sum(t1.score1) as score1, sum(t2.score) as score2 from Table2 as t2
left JOIN
(select name , score as score1 from Table1 )t1
on t2.name = t1.name
where score1 is null
group by name
---- if you want use the order add this "order by name" here in the end
and this will output :
NAME | SCORE1 |SCORE2
Jack | 15 | 16
Jane | 20 |(null)
Jill | 12 | 14
Jake | (null) | 15
John | (null) | 11
HERE SQLFIDDLE DEMO
Well, if MySQL had full outer join, you would use that. Here is an alternative method:
select id, name, MAX(score1) as score1, MAX(score2) as score2
from ((select id, name, score as score1, NULL as score2
from table1
) union all
(select id, name, null as score1, score as score2
from table1
)
) t
group by id, name
The idea is to get all information needed from each table, with the score in different columns, by using the union all and splitting the score into two separate columns.
The final group by brings them together with one row per id.
Try this:
select
name = Table1.name,
sum(Table1.score) as score1,
sum(Table2.Score) as score2
from Table1
full outer join
Table2
ON
Table2.name = Table1.name
where Table1.name is not null
group by table1.name
UNION
select
name = Table2.name,
sum(Table1.score) as score1,
sum(Table2.Score) as score2
from Table1
full outer join
Table2
ON
Table2.name = Table1.name
where Table2.name is not null
group by table2.name
order by score1 desc, score2

SQL "group by" use priority

I have a table where I can have multiple names for a given id like this:
a_table (id int, name varchar(100), priority int);
I need a query that will search on names but make sure it will return only 1 name for each id, and that name will be the one with the higher priority.
e.g. if my data are
1, AaaB, 2
1, AbbB, 1
1, AccB, 0
2, foo, 0
3, AddC, 0
I want my query for "A%" to return:
1, AaaB
3, AddC
I was thinking something like:
select * from a_table where name like 'A%' group by id;
But this will not guarantee that the value with the higher priority will be selected.
Any ideas?
I believe you want what the MySQL documentation calls the rows holding the group-wise maximum of a certain column:
For the task "For each article, find the dealer or dealers with the most expensive price":
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article)
ORDER BY article;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0001 | B | 3.99 |
| 0002 | A | 10.99 |
| 0003 | C | 1.69 |
| 0004 | D | 19.95 |
+---------+--------+-------+
You have to first get the highest priority per id and then filter on the names:
select t2.id, t2.name, t2.price
from (
select id, max(priority)
from a_table
group by id
) t1,
a_table t2
where t1.id = t2.id
and t1.priority = t2.priority
and t2.name like 'A%'
Taking #niktrs's valid suggestion, this is the same above query using the standard JOIN instead of where for joining tables. This is more preferred over the previous one
select t2.id, t2.name, t2.price
from (
select id, max(priority)
from a_table
group by id
) t1 JOIN a_table t2 ON t1.id = t2.id
and t1.priority = t2.priority
and t2.name like 'A%'
select *
from a_table t
join (
select max(Priority) MaxPriority, Name
from a_table a
where name like 'A%'
group by Name
)x where x.MaxPriority=a.Priority and x.Name=t.Name
On the basis the first column in the data example is the "Priority".
This is just the SQL linked from Alvaro's answer though.
select id, name
from a_table at
where
name like 'A%' and
priority = (
select max(priority)
from a_table
where (id = at.id) and (name like 'A%')
)
would this work out,
select distinct id,first_value(name)over(partition by id order by name)
from demo_tab t
where t.name like 'A%'
Sorry pratik,
it must have been
select distinct id,first_value(name)over(partition by id order by priority desc)
from demo_tab where name like 'A%'