MySQL使用不同的值优化查询计数,如果没有行,则使用NULL
我需要从一个时间少于其他时间的时刻表中获得不同运动员的数量。但棘手的是,如果根本没有时间进行比较,我需要得到NULL作为回报 让我举个例子:MySQL使用不同的值优化查询计数,如果没有行,则使用NULL,mysql,query-optimization,Mysql,Query Optimization,我需要从一个时间少于其他时间的时刻表中获得不同运动员的数量。但棘手的是,如果根本没有时间进行比较,我需要得到NULL作为回报 让我举个例子: CREATE TABLE `teams` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO teams VALUES (NULL, 'Texas'), (NULL,'Oklahoma'
CREATE TABLE `teams` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO teams
VALUES (NULL, 'Texas'), (NULL,'Oklahoma');
mysql> select * from teams;
+----+----------+
| id | name |
+----+----------+
| 1 | Texas |
| 2 | Oklahoma |
+----+----------+
CREATE TABLE `times` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`team_id` int(11) NOT NULL,
`time` decimal(8,2) NOT NULL,
`athlete` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `team_id` (`team_id`)
);
INSERT INTO times VALUES
(NULL, 1, 19.10, 'Dave'),
(NULL, 1, 19.09, 'Dave'),
(NULL, 1, 19.07, 'Dave'),
(NULL, 1, 19.56, 'John'),
(NULL, 1, 19.60, 'John'),
(NULL, 1, 19.75, 'John');
mysql> select * from times;
+----+---------+-------+---------+
| id | team_id | time | athlete |
+----+---------+-------+---------+
| 1 | 1 | 19.10 | Dave |
| 2 | 1 | 19.09 | Dave |
| 3 | 1 | 19.07 | Dave |
| 4 | 1 | 19.56 | John |
| 5 | 1 | 19.60 | John |
| 6 | 1 | 19.75 | John |
+----+---------+-------+---------+
到目前为止,我们有两个队。第一队有两名运动员,共6次,第二队分别没有运动员和2次
如果我想知道德克萨斯州有多少运动员的速度超过19.50,我可以做:
SELECT COUNT(DISTINCT athlete) FROM times WHERE time < 19.50 and team_id = 1;
+-------------------------+
| COUNT(DISTINCT athlete) |
+-------------------------+
| 1 |
+-------------------------+
这也是正确的,因为我们有两名来自德克萨斯州的运动员
但如果我想检查一下:有多少俄克拉何马州的运动员跑得比19.00快
这是正确的,如果我在德克萨斯州测试它,我得到:
问题是,这是计数时间,而不是不同的运动员,因此对于德克萨斯州,我将得到错误的计数
SELECT SUM(CASE
WHEN time < 19.50
THEN 1
ELSE 0
END) as count
FROM `times`
WHERE team_id = 1;
+-------+
| count |
+-------+
| 3 |
+-------+
我比19.50快3倍,而不是比19.50快1个运动员。怎么样
SELECT a.name
, MAX(b.athlete < 19.50) faster
FROM teams a
LEFT
JOIN times b
ON b.team_id = a.id
GROUP BY a.name;
那么
SELECT a.name
, MAX(b.athlete < 19.50) faster
FROM teams a
LEFT
JOIN times b
ON b.team_id = a.id
GROUP BY a.name;
好的,我想我找到了一个解决方案,它又有一个子查询,但至少我不需要重复所有的过滤器两次,如果没有更好的,现在就可以满足我了。这是:
SELECT
SUM(CASE WHEN a.time < 19.00 THEN 1 ELSE 0 END) as count
FROM (
SELECT athlete, min(time) as time
FROM times
WHERE team_id = 2 group by athlete
) a;
通过这种方式,我为团队2获取空值,为团队1获取0。好的,我想我找到了一个解决方案,该解决方案又有一个子查询,但至少我不需要重复所有的过滤器两次,如果没有更好的过滤器,现在就可以满足我了。这是:
SELECT
SUM(CASE WHEN a.time < 19.00 THEN 1 ELSE 0 END) as count
FROM (
SELECT athlete, min(time) as time
FROM times
WHERE team_id = 2 group by athlete
) a;
通过这种方式,我为团队2获取NULL,为团队1获取0“19.50”是一个字符串。19.50是一个数字mysql正确地将“19.50”转换为数字。不管怎样,19.50是一个字符串。19.50是一个数字mysql正确地将“19.50”转换为数字。不过修正了。很好的技巧,但是如果我用20.00改19.50,我需要得到2作为计数,因为有两个运动员比20.00快。我想我找到了一个解决方案,我会在几分钟后发布。很好的技巧,但是如果我用20.00改19.50,我需要得到2作为计数,因为有两名运动员的速度超过20.00。我想我找到了一个解决方案,我会在几分钟后发布。
SELECT SUM(CASE
WHEN time < 19.50
THEN 1
ELSE 0
END) as count
FROM `times`
WHERE team_id = 1;
+-------+
| count |
+-------+
| 3 |
+-------+
SELECT a.name
, MAX(b.athlete < 19.50) faster
FROM teams a
LEFT
JOIN times b
ON b.team_id = a.id
GROUP BY a.name;
SELECT
SUM(CASE WHEN a.time < 19.00 THEN 1 ELSE 0 END) as count
FROM (
SELECT athlete, min(time) as time
FROM times
WHERE team_id = 2 group by athlete
) a;