How to combine near same item by SQL?

后端 未结 6 690
既然无缘
既然无缘 2021-02-11 10:53

I have some data in database:

id user 
1 zhangsan 
2 zhangsan 
3 zhangsan 
4 lisi 
5 lisi 
6 lisi 
7 zhangsan 
8 zhangsan 

I want keep order, a

相关标签:
6条回答
  • 2021-02-11 11:19

    A little improvement to the selected answer would be not to have to define those variables. So this query can be solved in just a single statement:

    SELECT COUNT(*) cnt, user
    FROM (
        SELECT @num := @num + (@name != user) as number,
               @name := user as user
        FROM t, (select @num := 0, @name := '') as s
        ORDER BY id
    ) x
    GROUP BY number
    

    Output:

    | CNT |     USER |
    |-----|----------|
    |   3 | zhangsan |
    |   3 |     lisi |
    |   2 | zhangsan |
    

    Fiddle here

    0 讨论(0)
  • 2021-02-11 11:25

    if in oracle, you can do like below.

    SELECT NAME,
           num - lagnum
      FROM (SELECT lagname,
                   NAME,
                   num,
                   nvl(lag(num) over(ORDER BY num), 0) lagnum
              FROM (SELECT id,
                           lag(NAME) over(ORDER BY ID) lagname,
                           NAME,
                           lead(NAME) over(ORDER BY ID) leadname,
                           ROWNUM num
                      FROM (SELECT * FROM test ORDER BY ID))
             WHERE (lagname = NAME AND (NAME <> leadname OR leadname IS NULL))
                OR (lagname IS NULL AND NAME <> leadname)
                OR (lagname <> NAME AND leadname IS NULL)
             ORDER BY ID);
    
    0 讨论(0)
  • 2021-02-11 11:30

    if in sql server, oracle, db2...

        with x as(  
    select c.*, rn = row_number() over (order by c.id)
      from test c 
      left join test n
        on c.[user] = n.[user]
       and c.[id] + 1 = n.[id]   
     where n.id is null
    )
    select a.[user], a.id - coalesce(b.id, 0) 
      from x a
      left join x b
        on a.rn = b.rn + 1 
    
    0 讨论(0)
  • 2021-02-11 11:37

    I think what you are looking for is to COUNT(ID):

    SELECT COUNT(ID) FROM table GROUP BY user
    
    0 讨论(0)
  • 2021-02-11 11:40

    You cannot do this in sql without doing some sort of sequential (iterative) analysis. Remember sql is set operation language.

    0 讨论(0)
  • 2021-02-11 11:44

    If you try:

    SET @name:='',@num:=0;
    
    SELECT id,
           @num:= if(@name = user, @num, @num + 1) as number,
           @name := user as user
    FROM foo
    ORDER BY id ASC;
    

    This gives:

    +------+--------+------+
    | id   | number | user |
    +------+--------+------+
    |    1 |      1 | a    |
    |    2 |      1 | a    |
    |    3 |      1 | a    |
    |    4 |      2 | b    |
    |    5 |      2 | b    |
    |    6 |      2 | b    |
    |    7 |      3 | a    |
    |    8 |      3 | a    |
    +------+--------+------+
    

    So then you can try:

    SET @name:='',@num:=0;
    
    SELECT COUNT(*) as count, user
    FROM (
    SELECT @num:= if(@name = user, @num, @num + 1) as number,
           @name := user as user
    FROM foo
    ORDER BY id ASC
    ) x
    GROUP BY number;
    

    Which gives

    +-------+------+
    | count | user |
    +-------+------+
    |     3 | a    |
    |     3 | b    |
    |     2 | a    |
    +-------+------+
    

    (I called my table foo and also just used names a and b because I was too lazy to write zhangsan and lisi over and over).

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