use MySQL to update fields with group - mysql

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)

Related

Similar SQLs with session variable produce different result

MariaDB 10.1.18
Table P (id int AUTO_INCREMENT, rownum int, code int, s int, PRIMARY KEY(id));
select id, rownum, code, s from P order by id;
+----+--------+------+------+
| id | rownum | code | s |
+----+--------+------+------+
| 1 | 1 | 5 | 1 |
| 2 | 2 | 5 | 1 |
| 3 | 3 | 5 | 1 |
| 4 | 4 | 5 | 1 |
| 5 | 5 | 5 | 1 |
| 6 | 6 | 7 | 1 |
| 7 | 7 | 7 | 1 |
| 8 | 8 | 7 | 1 |
| 9 | 9 | 7 | 1 |
| 10 | 10 | 7 | 1 |
+----+--------+------+------+
Issue: the following 2 queries are very similar: 1st query join on id, 2nd join on rownum; the id and rownum columns are having the same values (see table above), but the query result is different in calculated column N:
Query 1: join on id column
SELECT P.id, P.rownum, P2.s,
IF(P2.s IS NULL, #val:=#val+1, #val) as N
FROM P CROSS JOIN (SELECT #val:=0) init
LEFT JOIN P P2
ON (P.id+1=P2.id AND P.s=1 AND P2.s=1 AND P.code = P2.code)
ORDER BY P.id;
+----+--------+------+------+
| id | rownum | s | N |
+----+--------+------+------+
| 1 | 1 | 1 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 3 | 1 | 0 |
| 4 | 4 | 1 | 0 |
| 5 | 5 | NULL | 1 |
| 6 | 6 | 1 | 1 |
| 7 | 7 | 1 | 1 |
| 8 | 8 | 1 | 1 |
| 9 | 9 | 1 | 1 |
| 10 | 10 | NULL | 2 |
+----+--------+------+------+
Query 2: join on rownum column
SELECT P.id, P.rownum, P2.s,
IF(P2.s IS NULL, #val:=#val+1, #val) as N
FROM P CROSS JOIN (SELECT #val:=0) init
LEFT JOIN P P2
ON (P.rownum+1=P2.rownum AND P.s=1 AND P2.s=1 AND P.code = P2.code)
ORDER BY P.id;
+----+--------+------+------+
| id | rownum | s | N |
+----+--------+------+------+
| 1 | 1 | 1 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 3 | 1 | 0 |
| 4 | 4 | 1 | 0 |
| 5 | 5 | NULL | 1 |
| 6 | 6 | 1 | 0 |
| 7 | 7 | 1 | 0 |
| 8 | 8 | 1 | 0 |
| 9 | 9 | 1 | 0 |
| 10 | 10 | NULL | 2 |
+----+--------+------+------+
As explicitly documented both in MariaDB knowledge base and MySQL manual, you should not read a user-defined variable and set its value in the same statement, unless this statement is SET. For other statements it is unsafe and the result is not guaranteed, as your example clearly demonstrates.
Additional note: variables you are talking about in your question are more commonly referred to as 'user-defined variables' or 'user variables', as opposed to 'system variables', 'global variables' and 'session variables', each of which imply system-defined variables, either all of them or limited to the given scope.

data unpivot list ids of after group_concat

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.

Mysql : select count when id have multiple same value

+------+---------+
| id | object |
+------+---------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 3 |
| 2 | 4 |
| 3 | 5 |
| 3 | 3 |
| 3 | 4 |
+------+---------+
i want to select count id where have a same value, so the result be, id 1 have 4 same value, id 2 have 2 same value, id 3 have 3 same value .
+------+
| id |
+------+
| 4 |
| 2 |
| 3 |
+------+
thanks for help, master.
SELECT id, COUNT(object) FROM tablename GROUP BY id
SELECT COUNT( * ) FROM `test` GROUP BY id

What is self join in mysql used for

What is this self join and why do we need this self join?. I have till date never used self joins.
See if these links helps you...
http://www.udel.edu/evelyn/SQL-Class3/SQL3_self.html
http://awads.net/wp/2006/07/11/back-to-basics-self-joins/
http://www.sqltutorial.org/sqlselfjoin.aspx
Good Luck!!!
there are number of reasons, and tons of examples are available on web
http://www.udel.edu/evelyn/SQL-Class3/SQL3_self.html
mysql> SELECT * FROM pr WHERE id>80;
+----+------+--------+
| id | ids | status |
+----+------+--------+
| 81 | 4 | 4 |
| 82 | 2 | 3 |
| 83 | 2 | 4 |
+----+------+--------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM pr WHERE id<18;
+----+------+--------+
| id | ids | status |
+----+------+--------+
| 1 | 1 | 1 |
| 5 | NULL | 2 |
+----+------+--------+
2 rows in set (0.01 sec)
identical requests :
mysql> SELECT * FROM pr AS t1 ,pr AS t2 WHERE t1.id<18 AND t2.id>80;
+----+------+--------+----+------+--------+
| id | ids | status | id | ids | status |
+----+------+--------+----+------+--------+
| 1 | 1 | 1 | 81 | 4 | 4 |
| 5 | NULL | 2 | 81 | 4 | 4 |
| 1 | 1 | 1 | 82 | 2 | 3 |
| 5 | NULL | 2 | 82 | 2 | 3 |
| 1 | 1 | 1 | 83 | 2 | 4 |
| 5 | NULL | 2 | 83 | 2 | 4 |
+----+------+--------+----+------+--------+
6 rows in set (0.00 sec)
mysql> SELECT * FROM pr AS t1 JOIN pr AS t2 ON t1.id<18 AND t2.id>80;
+----+------+--------+----+------+--------+
| id | ids | status | id | ids | status |
+----+------+--------+----+------+--------+
| 1 | 1 | 1 | 81 | 4 | 4 |
| 5 | NULL | 2 | 81 | 4 | 4 |
| 1 | 1 | 1 | 82 | 2 | 3 |
| 5 | NULL | 2 | 82 | 2 | 3 |
| 1 | 1 | 1 | 83 | 2 | 4 |
| 5 | NULL | 2 | 83 | 2 | 4 |
+----+------+--------+----+------+--------+
6 rows in set (0.00 sec)

How can I merge and count MySQL rows that are identical except for an ID column?

I want to be able to merge rows and find out how many are the same excluding the ID. For example, if I was to have this table:
+---------+-----------+-----------+
| ID | Col 1 | Col 2 |
+---------+-----------+ ----------+
| 1 | 1 | 5 |
| 2 | 1 | 5 |
| 3 | 4 | 9 |
| 4 | 3 | 9 |
| 5 | 1 | 5 |
| 6 | 1 | 5 |
| 7 | 1 | 5 |
| 8 | 4 | 9 |
+---------+-----------+-----------+
It would become:
+---------+-----------+-----------+---------+
| ID | Col 1 | Col 2 | Count |
+---------+-----------+ ----------+---------+
| 1 | 1 | 5 | 5 |
| 2 | 4 | 9 | 2 |
| 3 | 3 | 9 | 1 |
+---------+-----------+-----------+---------+
What would the query for this be?
beside the ID column in your result, to me it looks like you need:
SELECT Col1, Col2, Count(Col1)
FROM myTable
GROUP BY Col1, Col2
select col1,col2,count(*) as `count`
from table
group by col1,col2