我有一个有两列的表。
+------+------+
| data | num |
+------+------+
| a | |
| a | |
| a | |
| b | |
| b | |
| c | |
| d | |
| a | |
| b | |
+------+------+
我希望列“num”显示每个重复条目的增量计数器:
+------+------+
| data | num |
+------+------+
| a | 1 |
| a | 2 |
| a | 3 |
| b | 1 |
| b | 2 |
| c | 1 |
| d | 1 |
| a | 4 |
| b | 3 |
+------+------+
除了mySQL查询之外,这可以在没有任何其他脚本的情况下完成吗?
扩展问题here
答案 0 :(得分:14)
不幸的是,MySQL没有窗口功能,这是你需要的。所以你必须使用这样的东西:
最终查询
select data, group_row_number, overall_row_num
from
(
select data,
@num := if(@data = `data`, @num + 1, 1) as group_row_number,
@data := `data` as dummy, overall_row_num
from
(
select data, @rn:=@rn+1 overall_row_num
from yourtable, (SELECT @rn:=0) r
) x
order by data, overall_row_num
) x
order by overall_row_num
<强>解释强>
首先,内部选择,这会将模拟row_number
应用于表格中的所有记录(请参阅SQL Fiddle with Demo):
select data, @rn:=@rn+1 overall_row_num
from yourtable, (SELECT @rn:=0) r
查询的第二部分,将表格中的每一行与下一行进行比较,以查看它是否具有相同的值,如果不是,则启动group_row_number
结束(请参阅SQL Fiddle with Demo) :
select data,
@num := if(@data = `data`, @num + 1, 1) as group_row_number,
@data := `data` as dummy, overall_row_num
from
(
select data, @rn:=@rn+1 overall_row_num
from yourtable, (SELECT @rn:=0) r
) x
order by data, overall_row_num
最后一个选择,返回您想要的值,并按照您请求的顺序放回它们:
select data, group_row_number, overall_row_num
from
(
select data,
@num := if(@data = `data`, @num + 1, 1) as group_row_number,
@data := `data` as dummy, overall_row_num
from
(
select data, @rn:=@rn+1 overall_row_num
from yourtable, (SELECT @rn:=0) r
) x
order by data, overall_row_num
) x
order by overall_row_num
答案 1 :(得分:4)
这是一个简单的查询,可以做你想要的。
select id,data,rownum
from (
select id,
data,
@row:=if(@prev=data,@row,0) + 1 as rownum,
@prev:=data
from tbl
order by data,id
)t
我在每一行都加了一个id。但你不需要它。
答案 2 :(得分:0)
数据是否必须按照显示的顺序保留,还是可以按“数据”值排序?
如果您可以排序,那么您只需要跟踪当前的“数据”值,这可以通过变量来完成:
set @last_data = null;
set @count = 0;
select data, @count,
case when @last_data is null or data != @last_data then @count := 1 else @count := @count + 1 end as new_count,
@last_data := data, @count
from t20120917
order by data;
如果没有,我认为它会更复杂......
答案 3 :(得分:0)
它是这样的,但你需要创建程序
create procedure procname()
begin
DECLARE done,i,j int DEFAULT 0;
DECLARE n,m nvarchar(500) DEFAULT '';
DECLARE cur CURSOR FOR SELECT d.data,d.num FROM tablename AS d ORDER BY DATA;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
set m = n;
SET j = i;
fetch cur into n,i;
IF n = m
THEN
SET i = i+1;
// UPDATE here your TABLE but you will need one more colomn to be able to UPDATE ONLY one RAW that you need
ELSE
SET i = 0; //RESET indexer
END IF;
IF done = 1 THEN
LEAVE read_loop;
END IF;
END LOOP read_loop;
CLOSE cur;
end