出现在2列中的Mysql计数ID

时间:2013-07-07 14:43:17

标签: mysql sql count

我有一个包含这些列的表:

  • ID
  • USER_ID
  • player_in
  • player_out
  • 日期

我需要制作一个报告,计算每个“玩家”在player_in字段中的重复次数,如在player_out字段中。 例如,如果我在表中有这两行(按相应的顺序)。

id user_id player_in player_out
1  1       88        56
2  7       77        88

玩家88的结果将是2,而对于玩家56和77,只有1

2 个答案:

答案 0 :(得分:3)

使用使用union all的子查询将两列放入一列,然后使用标准count(*)

注意:因此,根据对此答案的评论中的进一步请求,查询包括进出的个别总数。

select
  player_id,
  count(*) as total,
  sum(ins) as ins,
  sum(outs) as outs
from (
  select
    player_in as player_id,
    1 as ins,
    0 as outs
  from mytable
  union all
  select player_out, 0, 1
  from mytable
) x
group by player_id

注意:您必须使用union all(而不仅仅是union),因为union会删除重复项,而union all则不会。{/ p>

答案 1 :(得分:2)

您可以使用交叉连接到2行虚拟表来取消忽略player_*列,然后对结果进行分组,如下所示:

SELECT
  player,
  COUNT(*) AS total_count
FROM (
  SELECT
    CASE WHEN x.is_in THEN t.player_in ELSE t.player_out END AS player
  FROM mytable t
  CROSS JOIN (SELECT TRUE AS is_in UNION ALL SELECT FALSE) x
) s
GROUP BY
  player
;

也就是说,原始表的每一行基本上都是重复的,并且该行的每个副本都提供player_inplayer_out,具体取决于派生表的is_in列是否为{{ 1}}或TRUE,以形成一个FALSE列。这种univoting方法可能比UNION方法suggested by @Bohemian表现更好,因为这种方式(物理)表只传递一次(但你需要测试和比较两种方法,以确定这种方法是否有任何实质性的好处在你的特殊情况下)。

要计算进出计数,正如您在上述答案的一条评论中所要求的那样,您可以扩展我的原始建议:

player

如您所见,派生表现在另外返回SELECT player, COUNT( is_in OR NULL) AS in_count, COUNT(NOT is_in OR NULL) AS out_count, COUNT(*) AS total_count FROM ( SELECT x.is_in, CASE WHEN x.is_in THEN t.player_in ELSE t.player_out END AS player FROM mytable t CROSS JOIN (SELECT TRUE AS is_in UNION ALL SELECT FALSE) x ) s GROUP BY player ;列本身,并且该列用于两个条件聚合,用于计算玩家进出的次数。 (如果您有兴趣,可以解释is_in技巧here。)

您还可以将OR NULL条目重写为COUNT(condition OR NULL)。这肯定会缩短这两个表达式,有些人还会发现SUM(condition)计算更清晰/更优雅的方法。在任何一种情况下,性能都可能没有差异,因此请选择适合您口味的方法。

可以找到第二个查询的SQL小提琴演示here