连续行中重复值的总和

时间:2019-07-12 11:14:33

标签: mysql sql

我有一张这样的桌子:

id col1 col2 col3
10  1          3
9   1    2     3
8        2     3
7        2     3
6   1    2    
5              3    

每列只有一个值或为空。例如。 Col1为1或为空。 Col2有2个或为空。

我只想获取两个连续行之间的重复值之和。 所以结果看起来像这样:

我需要获取每一行中总重复值的总和。

id col1 col2 col3   Count
10  1          3     2    (shows the repeating values between id10 & id9 rows)
9   1    2     3     2    (shows the repeating values between id9 & id8 rows)
8        2     3     1
7        2           1
6   1    2           0
5              3       

我用Google搜索并尝试了一些我在网络上发现的查询,但没有得到正确的结果。预先感谢您的帮助。

为进一步说明,例如: id10行具有(1,,3),而id9行具有(1,2,3)。因此有两个重复的值。因此计数为2。

4 个答案:

答案 0 :(得分:2)

如果ID是连续的并且没有空格,则可以使用自连接来实现:

select 
  t.*,
  coalesce((t.col1 = tt.col1), 0) + 
  coalesce((t.col2 = tt.col2), 0) + 
  coalesce((t.col3 = tt.col3), 0) count
from tablename t left join tablename tt
on tt.id = t.id - 1

请参见demo
结果:

| id  | col1 | col2 | col3 | count |
| --- | ---- | ---- | ---- | ----- |
| 10  | 1    |      | 3    | 2     |
| 9   | 1    | 2    | 3    | 2     |
| 8   |      | 2    | 3    | 1     |
| 7   |      | 2    |      | 1     |
| 6   | 1    | 2    |      | 0     |
| 5   |      |      | 3    | 0     |

答案 1 :(得分:2)

如果还有差距...

SELECT a.id 
     , a.col1 
     , a.col2 
     , a.col3 
     , COALESCE(a.col1 = b.col1,0) + COALESCE(a.col2 = b.col2,0) + COALESCE(a.col3 = b.col3,0) n 
  FROM 
     ( SELECT x.*
            , MIN(y.id) y_id 
         FROM my_table x 
         JOIN my_table y 
           ON y.id > x.id 
        GROUP 
           BY x.id
      ) a 
   LEFT
   JOIN my_table b 
     ON b.id = a.y_id;

如果您要重组架构,那么可以改成这样……

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL 
,val INT NOT NULL
,PRIMARY KEY(id,val)
);

INSERT INTO my_table VALUES
(10,1),
(10,3),
( 9,1),
( 9,2),
( 9,3),
( 8,2),
( 8,3),
( 7,2),
( 7,3),
( 6,1),
( 6,2),
( 5,3); 

SELECT a.id
     , COUNT(b.id) total 
  FROM 
     ( SELECT x.*
            , MIN(y.id) next 
         FROM my_table x 
         JOIN my_table y 
           ON y.id > x.id 
        GROUP 
           BY x.id
            , x.val
     ) a 
  LEFT 
  JOIN my_table b 
    ON b.id = a.next 
   AND b.val = a.val 
 GROUP 
    BY a.id;
+----+-------+
| id | total |
+----+-------+
|  5 |     0 |
|  6 |     1 |
|  7 |     2 |
|  8 |     2 |
|  9 |     2 |
+----+-------+

答案 2 :(得分:1)

您可以使用:

select t1_ID, t1_col1,t1_col2,t1_col3, count
  from
(
select t1.id as t1_ID, t1.col1 as t1_col1,t1.col2 as t1_col2,t1.col3 as t1_col3, t2.*,
       case when t1.col1 = t2.col1 then 1 else 0 end +
       case when t1.col2 = t2.col2 then 1 else 0 end +
       case when t1.col3 = t2.col3 then 1 else 0 end as count
  from tab t1
  left join tab t2 
    on t1.id = t2.id + 1
 order by t1.id
) t3
order by t1_ID desc;

Demo

答案 3 :(得分:1)

如果下一行的id值之间有间隙,则可以让user defined variables以表中的自然顺序为行显式分配值。其余逻辑与已经回答的逻辑相同。您可以在当前行号和下一行号之间进行内部联接,以获取col1col2col3的值,并使用coalesce来计算count

select derived_1.*,
  coalesce((derived_1.col1 = derived_2.col1), 0) + 
  coalesce((derived_1.col2 = derived_2.col2), 0) + 
  coalesce((derived_1.col3 = derived_2.col3), 0) count
from (
        select @row := @row + 1 as row_number,t1.*
        from tablename t1,(select @row := 0) d1
      ) derived_1
left join (
       select *
       from (
             select @row2 := @row2 + 1 as row_number,t2.*
             from tablename t2,(select @row2 := 0) d2
            ) d3
        ) derived_2
on derived_1.row_number + 1 = derived_2.row_number; 

演示: https://www.db-fiddle.com/f/wAzb67zSEfbZKg5RywQvC8/1