Mysql 选择多列计数,但仅当列值大于0时才包括该计数
我不确定我在标题中是否正确解释了这个问题,但基本上我有一个表,可以节省玩家的出场时间:Mysql 选择多列计数,但仅当列值大于0时才包括该计数,mysql,Mysql,我不确定我在标题中是否正确解释了这个问题,但基本上我有一个表,可以节省玩家的出场时间: CREATE TABLE `stagetimes` ( `steamid` VARCHAR(32) CHARACTER SET utf8 NOT NULL DEFAULT '', `name` VARCHAR(32) CHARACTER SET utf8 DEFAULT NULL, `mapname` VARCHAR(32) CHARACTER SET utf8
CREATE TABLE `stagetimes`
(
`steamid` VARCHAR(32) CHARACTER SET utf8 NOT NULL DEFAULT '',
`name` VARCHAR(32) CHARACTER SET utf8 DEFAULT NULL,
`mapname` VARCHAR(32) CHARACTER SET utf8 NOT NULL DEFAULT '',
`s1` FLOAT DEFAULT '-1',
`s2` FLOAT DEFAULT '-1',
`s3` FLOAT DEFAULT '-1',
`s4` FLOAT DEFAULT '-1',
`s5` FLOAT DEFAULT '-1'
)
engine=innodb
ALTER TABLE `stagetimes`
ADD PRIMARY KEY (`steamid`,`mapname`);
这张表实际上上升到了s35,但为了简单起见,我忽略了其余部分
一旦有人完成阶段1,就会插入一个新行,其中包含他们的steamid、姓名、地图名称和阶段1时间,其余列为-1,并在他们击败其他阶段后进行更新。然而,并非每个地图都有5个阶段,有些可能只有4个或更少,因此显然,如果玩家的列值为-1,该阶段不存在或尚未完成,因此没有从-1更新时间
我想选择一个特定玩家已经完成的阶段总数作为计数;我提出了一个有效的查询,但它非常长,我想知道是否有其他方法可以实现这一点:
SELECT Sum(stages)
FROM ((SELECT Count(`s1`) AS `stages`
FROM `stagetimes`
WHERE `steamid` = 'STEAM_1:0:00000000'
AND `s1` > 0)
UNION ALL
(SELECT Count(`s2`) AS `stages`
FROM `stagetimes`
WHERE `steamid` = 'STEAM_1:0:00000000'
AND `s2` > 0)
UNION ALL
(SELECT Count(`s3`) AS `stages`
FROM `stagetimes`
WHERE `steamid` = 'STEAM_1:0:00000000'
AND `s3` > 0)
UNION ALL
(SELECT Count(`s4`) AS `stages`
FROM `stagetimes`
WHERE `steamid` = 'STEAM_1:0:00000000'
AND `s4` > 0)
UNION ALL
(SELECT Count(`s5`) AS `stages`
FROM `stagetimes`
WHERE `steamid` = 'STEAM_1:0:00000000'
AND `s5` > 0)) t1
如果可以避免的话,我真的不想做35次
样本数据:
+-------------------+------------+---------------+--------+--------+--------+--------+--------+
| steamid | name | mapname | s1 | s2 | s3 | s4 | s5 |
+-------------------+------------+---------------+--------+--------+--------+--------+--------+
|STEAM_1:0:20019070 | fluffys | surf_catrix | 13.562 | 12.593 | 14.328 | 21.984 | -1 |
|STEAM_1:0:20019070 | fluffys | surf_beginner | 2.753 | 9.185 | 14.406 | 23.359 | 11.343 |
+-------------------+------------+---------------+--------+--------+--------+--------+--------+
根据该数据,查询应返回9,因为有9个阶段的值不为-1使用SUM()
而不是COUNT()
将其放入单个查询中。条件表达式为true时返回1
,为false时返回0
,因此您可以简单地添加它们
SELECT SUM((s1 > 0) + (s2 > 0) + (s3 > 0) + (s4 > 0) + (s5 > 0)) AS total_stages
FROM stagetimes
WHERE steamid = 'STEAM_1:0:00000000'
重新组织您的模式可能会更好。不要将每个阶段作为表中的一列,而是为每个阶段单独设置一行,将阶段编号作为一列。那么你就只有实际存在的阶段的行了。顶部的
stagetimes
表与查询中的ck\u wrcps
有什么关系?我的坏,修复了表名这对我不起作用,我在原始帖子中添加了一些示例数据,你的查询很可能只返回2
,因为有2条记录,但我试图计算所有不是-1的阶段。我最初也用这种方式组织模式,但是有太多的记录,这是因为担心运算符优先级问题。每个条件都需要括号。