How to insert max 3 results in different columns? - mysql

I would like to insert max 3 results of a column into 3 different columns.
SELECT
t.name,
m.top_marks
FROM
table_name t,
(SELECT
marks
FROM table_name
WHERE rownum <=3
ORDER BY marks DESC) m
GROUP BY column_name DESC;
This can help me to get top 3 marks right? but what if i want to store top 3 results in 3 new columns? Marks1, marks2, marks3?

I can't say I really understand what you are going for... But it sounds like you might want the LIMIT operator. See this:
SQL - Select first 10 rows only?
So maybe something like this?
SELECT
t.name,
m.top_marks
FROM
table_name t,
(SELECT
marks
FROM table_name
ORDER BY marks DESC
LIMIT 3) m
GROUP BY column_name DESC;

You can do this with the group_concat()/substring_index() method:
SELECT t.name,
substring_index(m.marks, ',', 1) as Mark1,
substring_index(substring_index(m.marks, ',', 2), ',', -1) as Mark2,
substring_index(substring_index(m.marks, ',', 3), ',', -1) as Mark3
m.top_marks
FROM table_name t cross join
(SELECT group_concat(marks order by marks desc) as marks
FROM table_name
) m
GROUP BY column_name DESC;
If it is sufficient to have them in one column with commas separating the values:
SELECT t.name, substring_index(m.marks, ',', 3) as Marks3
FROM table_name t cross join
(SELECT group_concat(marks order by marks desc) as marks
FROM table_name
) m
GROUP BY column_name DESC;

Related

How can i get just the latest 2 records on each group when using GROUP_CONCAT?

SELECT id, GROUP_CONCAT(type SEPARATOR '/') as types FROM `sems` GROUP by year
I just want to get the 2 latest record on each group
If you are running MySQL 8.0, you can use row_number() for this. You need an ordering column to define the latest record, I assumed ordering_id:
select id, group_concat(type order by rn separator '/') types
from (
select id, type, row_number() over(partition by id order by ordering_id desc) rn
from sems
) t
where rn <= 2
group by id
In earlier versions, one option is to filter with a subquery:
select id, group_concat(type order by rn separator '/') types
from sems s
where s.ordering_id >= (
select s1.ordering_id
from sems s1
where s1.id = s.id
order by s1.ordering_id desc
limit 2
)
group by id
This assumes that (id, ordering_id) tuples are unique. If not, and there are ties in the top 2, all related records will be taken into account.
If your data is not too numerous, you can use:
SELECT id,
SUBSTRING_INDEX(GROUP_CONCAT(type ORDER BY ? DESC SEPARATOR '/'), '/', -2) as types
FROM `sems`
GROUP by year;.
The ? is for the column used to define "latest"

Can I concatenate multiple MySQL Column into One Column?

Good day i would like to ask if this is possible in MySQL
SELECT id,label,name,age,sex FROM table LIMIT 3
Output
[row1] id,label,name,age,sex
[row2] id,label,name,age,sex
[row3] id,label,name,age,sex
My Output Needed
[row1] id
[row2] label
[row3] name
[row4] age
[row5] sex
[row6] id
[row7] label
[row8] name
[row9] age
[row10] sex
[row11] id
[row12] label
[row13] name
[row14] age
[row15] sex
You can do something like this:
SELECT * FROM
((SELECT id AS id1, 1 AS rownum, 'id' AS colname, id AS Data_value FROM mytable LIMIT 3)
UNION ALL
(SELECT id, 2, 'label', label FROM mytable LIMIT 3)
UNION ALL
(SELECT id, 3, 'name', name FROM mytable LIMIT 3)
UNION ALL
(SELECT id, 4, 'age', age FROM mytable LIMIT 3)
UNION ALL
(SELECT id, 5, 'sex', sex FROM mytable LIMIT 3)) A
ORDER BY id1, rownum
Here's a fiddle: https://www.db-fiddle.com/f/dvg6x1vBg6H5bDNp9VZxQa/4
I've added 3 additional column id AS id1, rownum and colname. The first two additional column is used for ORDER BY at the outer query. If you don't want to see the additional column, you can just type SELECT Data_value FROM ... at the outer query.
You can use group_concat() to aggregate rows by string concatenation. For the LIMIT to work you then need to use a derived table. But you should be careful with a LIMIT without an ORDER BY. As the order of a query result can be random unless an explicit ORDER BY is issued, you may get different results each time you run the query.
SELECT group_concat(id,
'\n',
label,
'\n',
name,
'\n',
age,
'\n',
sex
SEPARATOR '\n')
FROM (SELECT id,
label,
name,
age,
sex
FROM elbat
LIMIT 3) x;
If you just want to concatenate the columns but keep the rows just use concat().
SELECT concat(id,
'\n',
label,
'\n',
name,
'\n',
age,
'\n',
sex)
FROM elbat
LIMIT 3;
yes,you can use union all like below :
SELECT id FROM table LIMIT 3
union all
SELECT label FROM table LIMIT 3
union all
SELECT name FROM table LIMIT 3
union all
SELECT age FROM table LIMIT 3
union all
SELECT sex FROM table LIMIT 3
That what you looking is to Unpivot data. For more info about pivot and unpivot you can check here.
http://archive.oreilly.com/oreillyschool/courses/dba1/dba110.html
Unfortunately there is no easy way to unpivot in mysql.
The below script will work for MySQL 8.0
set #rowNum :=0;
set #string :=(
select group_concat(id,',',label,',',name,',',age,',',sex separator ',')
from (
select id, label, name, age, sex from mytable limit 3
) x
);
with recursive
R1 as ( select #string as items),
R2 as ( select 1 as n
union
select n + 1 from R2, R1
where n <= length(items) - length(replace(items, ',', '')))
select distinct #rowNum := #rowNum+1 as rowNum, substring_index(substring_index(items, ',', n), ',', -1) output from R2, R1;

store multiple query results at a time (mysql)

I want to store the results of query
SELECT column_name from table_name limit 2
into variables, says, #w1 , #w2
What are the correct syntax?
I tried
"Set #w1, #w2 = (SELECT column_name from table_name limit ); "
and similar ones but it hasn't work.
Thank.
You can try the following:
SELECT * FROM
(SELECT #a := (SELECT column_name FROM table_name ORDER BY value LIMIT 1) as a) a,
(SELECT #b := (SELECT column_name FROM table_name ORDER BY value LIMIT 1 OFFSET 1) as b) b
Please note that limit won't make much sense if you do not use ORDER BY.

Sql - count the number of occurence for each duplicate value

Edit: What I want is to rank the frequency of all duplicates. I tried to use the code suggested earlier:
SELECT
t.*,
#rn:=IF(#name = name,
#rn + 1,
IF(#name:=name, 1, 1)) freq
FROM
(SELECT
*
FROM
student
ORDER BY name) t
CROSS JOIN
(SELECT #name:=NULL, #rn:=0) t2;
This, however, were able to count the frequency but only if they are consecutively ordered. See image below:
Instead of being counted as 3, number 1 under id 6 was counted back to 1.
It seems like you need every occurrence of the name, so a simple group won't do. Try something like this:
SELECT s.name AS "Name of Student",
(SELECT COUNT(name) FROM student ss WHERE s.name = ss.name) AS "Frequency of Late"
FROM student s
SELECT
name, COUNT(*)
FROM
TableName
GROUP BY
name
This query should work for you.
Use user variables for this:
SELECT
t.*,
#rn:=IF(#name = name,
#rn + 1,
IF(#name:=name, 1, 1)) freq
FROM
(SELECT
*
FROM
student
ORDER BY name) t
CROSS JOIN
(SELECT #name:=NULL, #rn:=0) t2;
EDIT:
If you want to order by date and freq later, you can do:
select * from (
/* the above query */
) t order by the_date_column desc, freq;
EDIT 2:
For the updated question, see below:
SELECT
*
FROM
(SELECT
t.*,
#rn:=IF(#number = number, #rn + 1, IF(#number:=number, 1, 1)) freq
FROM
(SELECT
*
FROM
your_table
ORDER BY number) t
CROSS JOIN (SELECT #number:=NULL, #rn:=0) t2) t
ORDER BY id;
DEMO # SQLFiddle
This is your solution
SELECT
Student_Name AS StudentName,count(Student_Name) Total
FROM
Student_Table
GROUP BY
Student_Name`

MySQL: Why does where clause in subselect on result of another subselect not work?

I have this select statement:
select A.id,
(select id from B order by rand() limit 1)b1,
(select id from B where not id in(b1) order by rand() limit 1)b2,
(select id from B where not id in(b1,b2) order by rand() limit 1)b3,
(select id from B where not id in(b1,b2,b3) order by rand() limit 1)b4,
(select id from B where not id in(b1,b2,b3,b4) order by rand() limit 1)b5
from A
It's not very fast, it doesn't give me an error, but also doesn't do what I want.
I want to read 5 random id's from Table B and connect them to Table A.
So far so good, i get a result with 5 id's from Table B, BUT there are doubles.
Even though i have this where clause that should prevent doubles, i get them.
For example A.id:1 has b1=1, b2=6, b3=1, b4=9, B5=3
I would understand if MySQL throws an error because it can't handle the statement, but there is nothing, so I think it should work, but it doesn't.
Anyone has an answer to this?
Edit:
It doesn't matter if the result looks like this(subquery):
1:2,7,3,9,6
or like this(join):
1:2
1:7
1:3
1:9
1:6
As long as every A.id has different B.id's. It's ok for two or more A.Id's to have the same B.id's, but it should be coincidental.
Still the question why MySQL accepts the query and gives a wrong result.
select id, b1, b2, b3, b4, b5
from (
select A.id,
# := (select GROUP_CONCAT(DISTINCT id ORDER BY RAND()) AS ids from B),
SUBSTRING_INDEX(SUBSTRING_INDEX(#, ',', 1), ',', -1) b1,
SUBSTRING_INDEX(SUBSTRING_INDEX(#, ',', 2), ',', -1) b2,
SUBSTRING_INDEX(SUBSTRING_INDEX(#, ',', 3), ',', -1) b3,
SUBSTRING_INDEX(SUBSTRING_INDEX(#, ',', 4), ',', -1) b4,
SUBSTRING_INDEX(SUBSTRING_INDEX(#, ',', 5), ',', -1) b5
from A
) t
Example: http://sqlfiddle.com/#!2/d7df9/9
Please check this post for selecting random rows: How to randomly select rows in SQL? You can then join those with the other table
SELECT B.id
FROM B JOIN A ON B.id=A.id
ORDER BY RAND()
LIMIT 5