data unpivot list ids of after group_concat - mysql

Here is link to : Sqlfiddle
contents of my table
mysql> select * from tb_dts;
+----+------+------+
| Id | key1 | key2 |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 1 |
| 4 | 2 | 1 |
| 5 | 2 | 1 |
| 6 | 2 | 1 |
| 7 | 2 | 1 |
| 8 | 1 | 2 |
| 9 | 1 | 2 |
| 10 | 1 | 2 |
| 11 | 1 | 2 |
| 12 | 1 | 2 |
| 13 | 3 | 1 |
| 14 | 3 | 1 |
| 15 | 3 | 1 |
| 16 | 3 | 1 |
| 17 | 2 | 2 |
| 18 | 2 | 2 |
| 19 | 2 | 2 |
| 20 | 2 | 3 |
| 21 | 2 | 3 |
| 22 | 2 | 3 |
| 23 | 3 | 2 |
| 24 | 3 | 2 |
| 25 | 3 | 2 |
| 26 | 3 | 2 |
+----+------+------+
26 rows in set (0.00 sec)
This is what I tried
mysql> select group_concat(id) from tb_dts group by key1,key2 limit 0,4;
+------------------+
| group_concat(id) |
+------------------+
| 1,2,3 |
| 8,9,10,11,12 |
| 4,5,6,7 |
| 17,18,19 |
+------------------+
4 rows in set (0.00 sec)
mysql> select id from tb_dts group by key1,key2 limit 0,4;
+----+
| id |
+----+
| 1 |
| 8 |
| 4 |
| 17 |
+----+
4 rows in set (0.00 sec)
This is what I expect to get as output for group by key1,key2 limit 0,4; : I want all id in one column, which falls within a limit group by key1 and key2, I don't know how to get it group_concat can't help me on this
for first 4 unique combination of key1,key2 what all id falls is my question that is using group by key1,key2 limit 0,4;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 4 |
| 5 |
| 6 |
| 7 |
| 17 |
| 18 |
| 19 |
+----+
15 rows in set (0.00 sec)
Table Structure
DROP TABLE IF EXISTS `tb_dts`;
CREATE TABLE `tb_dts` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`key1` int(11) DEFAULT '-99',
`key2` int(11) DEFAULT '-99',
PRIMARY KEY (`Id`),
KEY `main` (`key1`,`key2`)
) ENGINE=MyISAM AUTO_INCREMENT=27 DEFAULT CHARSET=latin1;
LOCK TABLES `tb_dts` WRITE;
INSERT INTO `tb_dts` VALUES (1,1,1),(2,1,1),(3,1,1),(4,2,1),(5,2,1),(6,2,1),(7,2,1),(8,1,2),(9,1,2),(10,1,2),(11,1,2),(12,1,2),(13,3,1),(14,3,1),(15,3,1),(16,3,1),(17,2,2),(18,2,2),(19,2,2),(20,2,3),(21,2,3),(22,2,3),(23,3,2),(24,3,2),(25,3,2),(26,3,2);
UNLOCK TABLES;

Use the Separator as below
select group_concat(id SEPARATOR '\n') from tb_dts group by key1,key2

If order doesn't matter then try :
See Output here : SQL Fiddle
select id
from tb_dts
where (key1,key2) in (
select key1,key2
from (
select distinct key1,key2 from tb_dts limit 0,4
) as sub
);

There is a way to solve question.
First you have to create a Table like
CREATE TABLE `Tmp` (
`Id` int(11)
);
And then, after you run the code
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 0,1;
--#TmpStr = "1,2,3"
Write a funtion to Split #TmpStr by "," and Insert into Tmp separately.
And keep doing same thing for
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 1,1;
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 2,1;
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 3,1;
it will show the result like you want.

Related

MYSQL: How to select every 4th row STARTING from 3rd row?

meaning the result should be selecting 3rd, 7th, 11th, 15 rows etc.
Every row has an ID, in ascending order.
I am stuck on this for hours! Any help is highly appreciated!
A simpler way would be to use mod on the id itself:
select * from table where (id + 1) mod 4 = 0;
Suppose your schema is:
CREATE TABLE t1 (
id int(11) DEFAULT NULL,
data varchar(20) DEFAULT NULL
);
mysql> select * from t1;
+------+--------+
| id | data |
+------+--------+
| 1 | abc-1 |
| 2 | abc-2 |
| 3 | abc-3 |
| 4 | abc-4 |
| 5 | abc-5 |
| 6 | abc-6 |
| 7 | abc-7 |
| 8 | abc-8 |
| 9 | abc-9 |
| 10 | abc-10 |
| 11 | abc-11 |
| 12 | abc-12 |
| 13 | abc-13 |
| 14 | abc-14 |
| 15 | abc-15 |
| 16 | abc-16 |
+------+--------+
16 rows in set (0.00 sec)
mysql> select id,data from (select mod(#r:=#r+1,4) as isfetch,id,data from t1,(select #r:=0) s) k where k.isfetch=0 order by id;
+------+--------+
| id | data |
+------+--------+
| 4 | abc-4 |
| 8 | abc-8 |
| 12 | abc-12 |
| 16 | abc-16 |
+------+--------+
4 rows in set (0.01 sec)

Show one column and multiple column result is different by sort multiply in mysql

Why A and B are in different order?
(1)sql1
mysql> select postid from mytable where uid=1302754505 order by check_status asc, postid desc limit 15;
+---------------------+
| postid |
+---------------------+
| 6478974144597095625 |
| 6478973839654417609 |
| 6477718983354512585 |
| 6477718467958437065 |
| 6475650432615478473 |
| 6475650174917440713 |
| 6475649947284174025 |
| 6471209260337755337 |
| 6478983597820114121 |
+---------------------+
9 rows in set (0.02 sec)
(2)sql2
mysql> select postid, check_status from mytable where uid=1302754505 order by check_status asc, postid desc limit 15;
+---------------------+--------------+
| postid | check_status |
+---------------------+--------------+
| 6478983597820114121 | 0 |
| 6477718983354512585 | 1 |
| 6477718467958437065 | 1 |
| 6475650432615478473 | 1 |
| 6475650174917440713 | 1 |
| 6475649947284174025 | 1 |
| 6471209260337755337 | 1 |
| 6478974144597095625 | 5 |
| 6478973839654417609 | 5 |
+---------------------+--------------+
The check_status is not sorted in sql1? I don't understand why sql1 and sql2 result is different.
Our mysql-proxy fix some sql, so I get some different result.

how can i get the name which age is max in his grade

how can i get the name who's age is max in his grade
Table information:
mysql> select * from stu;
+----+------+------+-------+
| id | name | age | grade |
+----+------+------+-------+
| 1 | a | 11 | 1 |
| 2 | b | 12 | 1 |
| 3 | c | 13 | 1 |
| 4 | d | 11 | 2 |
| 5 | e | 12 | 2 |
| 6 | f | 13 | 2 |
+----+------+------+-------+
6 rows in set (0.00 sec)
mysql> describe stu;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(1) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| grade | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
in this way i can get the max age and grade,but how can i get the name who's age is max in his grade.
mysql> select max(age),grade from stu group by grade;
+----------+-------+
| max(age) | grade |
+----------+-------+
| 13 | 1 |
| 13 | 2 |
+----------+-------+
2 rows in set (0.00 sec)
You could try this:
SELECT A.*
FROM STU A
INNER JOIN (SELECT MAX(AGE) AS MAX_AGE,GRADE FROM STU GROUP BY GRADE ) B ON A.GRADE = B.GRADE AND A.AGE= B.MAX_AGE
Try this:
select max(name), max(age),grade from stu
group by grade

How to sort the result of multiple queries alternatively?

I have a query made of three select clause like this:
select id, colors from table1
union all
select id, numbers from table2
union all
select id, names from table3
Also here is the tables structure:
// table1 // table2 //table3
+----+--------+ +----+---------+ +----+-------+
| id | colors | | id | numbers | | id | names |
+----+--------+ +----+---------+ +----+-------+
| 1 | red | | 1 | ten | | 1 | jack |
| 2 | green | | 2 | two | | 2 | peter |
| 3 | blue | | 3 | one | +----+-------+
| 4 | yellow | | 4 | three |
+----+--------+ | 5 | six |
| 6 | five |
+----+---------+
Now I want this order for the results:
+----+--------+
| id | colors |
+----+--------+
| 1 | red |
| 2 | ten |
| 3 | jack |
| 4 | green |
| 5 | two |
| 6 | peter |
| 7 | blue |
| 8 | one |
| 9 | yellow |
| 10 | three |
| 11 | six |
| 12 | five |
+----+--------+
How can I implement that? (it should be noted, order by 1,2,3 does not work for me)
This is how you can do this
select #rn:=#rn+1 as id,colors from (
(select #rn1:= #rn1+1 as rn,colors from table1,(select #rn1:=0)x order by id )
union all
(select #rn2:= #rn2+1 as rn,numbers as colors from table2,(select #rn2:=0.5)x order by id)
union all
(select #rn3:= #rn3+1 as rn,names as colors from table3,(select #rn3:=0.6)x order by id )
)x,(select #rn:=0)y order by rn ;
The idea is to assign a rn value for each table item and need to make sure that these values are always in ascending order
So if you run the query for each table you will have
mysql> select #rn1:= #rn1+1 as rn,colors from table1,(select #rn1:=0)x order by id;
+------+--------+
| rn | colors |
+------+--------+
| 1 | red |
| 2 | green |
| 3 | blue |
| 4 | yellow |
+------+--------+
4 rows in set (0.00 sec)
mysql> select #rn2:= #rn2+1 as rn,numbers as colors from table2,(select #rn2:=0.5)x order by id;
+------+--------+
| rn | colors |
+------+--------+
| 1.5 | ten |
| 2.5 | two |
| 3.5 | one |
| 4.5 | three |
| 5.5 | six |
| 6.5 | five |
+------+--------+
6 rows in set (0.00 sec)
mysql> select #rn3:= #rn3+1 as rn,names as colors from table3,(select #rn3:=0.6)x order by id;
+------+--------+
| rn | colors |
+------+--------+
| 1.6 | jack |
| 2.6 | peter |
+------+--------+
2 rows in set (0.00 sec)
Here you can see table1 rn values are 1,2,3,....
table2 values are 1.5,2.5,3.5,....
table3 values are 1.6,2.6,....
so finally when you order the result with all rn it will be as
1,1.5,1.6,2,2.5,2.6,....

use MySQL to update fields with group

id item_id item_order
--- ---------- -----------
1 1 0
2 1 0
3 1 0
4 2 0
5 2 0
6 2 0
7 3 0
8 3 0
9 3 0
10 3 0
How to use MySQL statement to update the order fields to:
id item_id item_order
--- ---------- -----------
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 3
7 3 1
8 3 2
9 3 3
10 3 4
Subquery can provide an elegance solution. Assuming your table is called test:
UPDATE test a SET item_order = (
SELECT count(*) FROM ( SELECT id, item_id FROM test ) b
WHERE a.item_id = b.item_id AND b.id <= a.id
)
How it works? For each row it would query the number of rows with same item_id and lower or equal id. This may be not as scalable as other solutions, I haven't tested, but for smaller tables this is easier to understand and update.
Notice that b is another subquery. This would force MySQL to create an internal temp table so that it won't complain we are reading from the table we are updating.
do this
create table tmp
(
id int(10) unsigned,
`order` int(10) unsigned auto_increment,
... // any other columns
primary key (id, `order`)
);
insert into tmp select * from old_table; // you can specify order if you want to
after getting the order correctly,
you can then remove the primary key on two columns
NOTE -- avoid reserved words as column name at all cost
IT WORKS
mysql> select * from test;
+------+--------+
| id | orders |
+------+--------+
| 1 | 0 |
| 1 | 0 |
| 1 | 0 |
| 2 | 0 |
| 2 | 0 |
| 2 | 0 |
| 2 | 0 |
+------+--------+
7 rows in set (0.00 sec)
mysql> insert into tmp select * from test;
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select * from tmp;
+----+--------+
| id | orders |
+----+--------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
+----+--------+
7 rows in set (0.00 sec)
mysql> desc tmp;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(10) | NO | PRI | 0 | |
| orders | int(10) | NO | PRI | NULL | auto_incrent |
+--------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
Select version:
select id,item_id,
#num:= if(#item_id=item_id,#num+1,1) as posit,
#item_id:=item_id as itid
from tab,(select #num:=0,#item_id:=0) as t order by item_id,id
+----+---------+-------+------+
| id | item_id | posit | itid |
+----+---------+-------+------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 1 |
| 3 | 1 | 3 | 1 |
| 4 | 2 | 1 | 2 |
| 5 | 2 | 2 | 2 |
| 6 | 2 | 3 | 2 |
| 7 | 3 | 1 | 3 |
| 8 | 3 | 2 | 3 |
| 9 | 3 | 3 | 3 |
| 10 | 3 | 4 | 3 |
+----+---------+-------+------+
10 rows in set (0.33 sec)
Update version:
update tab as t1
inner join (
select id,item_id,
#num:= if(#item_id=item_id,#num+1,1) as posit,
#item_id:=item_id as itid
from tab,(select #num:=0,#item_id:=0) as t order by item_id,id )
as t2
set t1.item_order = t2.posit
where t1.id = t2.id
+----+---------+------------+
| id | item_id | item_order |
+----+---------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 2 | 3 |
| 7 | 3 | 1 |
| 8 | 3 | 2 |
| 9 | 3 | 3 |
| 10 | 3 | 4 |
+----+---------+------------+
10 rows in set (0.00 sec)