在这种情况下如何返回重复值的数量?

时间:2014-04-22 14:28:30

标签: mysql

在mysql中,我有下表'Log':

id_user       cod          info
  1            A        random_info1
  1            A        random_info1
  1            A        random_info1
  1            A        random_info2
  1            B        random_info2
  1            B        random_info2
  1            B        random_info3
  1            B        random_info3
  2            A        random_info4
  2            A        random_info4
  2            B        random_info5
  2            B        random_info5
  2            B        random_info5
  2            B        random_info6

使用此查询:

SELECT
  id_user,
  SUM(cod = 'A') as A,
  SUM(cod = 'B') as B
FROM
  Log
GROUP BY
  id_user

我得到每个'id_user:

的每个'cod'的数量
id_user        A       B
  1            4       4
  2            2       4

现在,再加上之前的结果,我需要在“信息”中再次显示“info”中的值,对于每个“cod”,如:

id_user        A       B       A_repeated       B_repeated
  1            4       4          2                2
  2            2       4          1                2

id_user ='1'的A_repeated是2,因为random_info1在首次出现后出现两次。

id_user ='1'的B_repeated为2,因为random_info2和random_info3首次出现(每个)一次。

我在查询中需要做哪些更改才能获得这些结果?

1 个答案:

答案 0 :(得分:1)

你走了:))

SELECT
  id_user,
  SUM(cod = 'A') as A,
  SUM(cod = 'B') as B,
  SUM(cod = 'A' && is_repeating) AS A_repeating,
  SUM(cod = 'B' && is_repeating) AS B_repeating
FROM
(
select
l.*
, @is_repeating := if(@prev_id_user = id_user && @prev_cod = cod && @prev_info = info, 1, 0) as is_repeating
, @prev_id_user := id_user
, @prev_cod := cod
, @prev_info := info
from
Log l
, (select @prev_id_user:=null, @prev_cod:=null, @prev_info:=null, @is_repeating:=0) var_init
order by id_user, cod, id
) Log  
GROUP BY
  id_user

我需要补充一下,我添加了一个auto_increment列,我按顺序使用了(这很重要!)。就像我在上面的评论中已经说过的那样,除非你指定它,否则数据库表中没有顺序。你不能在没有order by子句的情况下依赖相同的顺序,即使看起来你可以这样做。

<强>更新

似乎我误解了你一点。这是一个更正版本,A_repeating所需的结果为3:

SELECT
  id_user,
  SUM(cod = 'A') as A,
  SUM(cod = 'B') as B,
  SUM(cod = 'A' && is_repeating) AS A_repeating,
  SUM(cod = 'B' && is_repeating) AS B_repeating
FROM
(
select
l.*
, @is_repeating := if(@prev_id_user = id_user && @prev_cod = cod && @prev_info = info, 1, 0) as is_repeating
, @prev_id_user := id_user
, @prev_cod := cod
, @prev_info := info
from
Log l
, (select @prev_id_user:=null, @prev_cod:=null, @prev_info:=null, @is_repeating:=0) var_init
order by id_user, cod, info
) Log  
GROUP BY
  id_user