MySQL - Get a counter for each duplicate value

后端 未结 4 774
时光说笑
时光说笑 2020-12-10 13:08

I have a table with two columns.

+------+------+
| data | num  | 
+------+------+
| a    |      | 
| a    |      |
| a    |      |
| b    |      |
| b    |            


        
相关标签:
4条回答
  • 2020-12-10 13:32

    Unfortunately, MySQL does not have windowing functions which is what you will need. So you will have to use something like this:

    Final Query

    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
    

    see SQL Fiddle with Demo

    Explanation:

    First, inner select, this applies a mock row_number to all of the records in your table (See SQL Fiddle with Demo):

    select data, @rn:=@rn+1 overall_row_num
    from yourtable, (SELECT @rn:=0) r
    

    Second part of the query, compares each row in your table to the next one to see if it has the same value, if it doesn't then start the group_row_number over (see 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
    

    The last select, returns the values you want and places them back in the order you requested:

    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
    
    0 讨论(0)
  • 2020-12-10 13:41

    Does the data have to stay in the order shown, or can we sort by the 'data' value?

    If you can sort, then you only have to keep track of the current 'data' value, which can be done with variables:

    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;
    

    If not, I think it'll be more complex...

    0 讨论(0)
  • 2020-12-10 13:51

    it is something like this, but you will need to create procedure

    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
    
    0 讨论(0)
  • 2020-12-10 13:57

    Here is a simple query that will do what you want.

    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
    

    I have included an id on each row. But you don't need it.

    Go fiddle: http://sqlfiddle.com/#!2/1d1f3/11/0

    Credit: Want Row Number on Group of column in MY SQL?

    0 讨论(0)
提交回复
热议问题