ich die Zählung von verschiedenen Athleten von einem mal Tisch bekommen müssen wo Zeit weniger als einige andere-Zeit ist. Aber der schwierige Teil ist, dass , wenn es überhaupt keine Zeiten gibt (zum Vergleich, Ich brauche NULL im Gegenzug erhalten).MySQL eine Abfrage COUNT-ing DISTINCT Werte oder NULL optimieren, wenn keine Zeilen
Lassen Sie mich Ihnen ein Beispiel geben:
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 |
+----+---------+-------+---------+
Bisher haben wir zwei Teams haben. Team 1
hat zwei Athleten mit 6 mal und Team 2
hat keine Athleten (und Zeiten jeweils).
Wenn ich will wissen, was ich tun kann:
SELECT COUNT(DISTINCT athlete) FROM times WHERE time < 19.50 and team_id = 1;
+-------------------------+
| COUNT(DISTINCT athlete) |
+-------------------------+
| 1 |
+-------------------------+
was richtig ist.
Und wenn ich will How many Athletes from Texas are faster than 19.00
SELECT COUNT(DISTINCT athlete) FROM times WHERE time < 19.00 and team_id = 1;
+-------------------------+
| COUNT(DISTINCT athlete) |
+-------------------------+
| 0 |
+-------------------------+
auch richtig ist zu überprüfen (denn wir haben zwei Athleten von Texas
).
Aber wenn ich überprüfen möchten: How many Athletes from Oklahoma are faster than 19.00
SELECT COUNT(DISTINCT athlete) FROM times WHERE time < 19.00 and team_id = 2;
+-------------------------+
| COUNT(DISTINCT athlete) |
+-------------------------+
| 0 |
+-------------------------+
ist nicht korrekt weil wir keine Zeiten von Oklahoma
haben. Also hier muss ich NULL
im Gegenzug bekommen.
ich es geschafft, eine Lösung mit einer Unterabfrage zu finden:
SELECT
IF(
EXISTS(
SELECT 1 FROM times WHERE team_id = 2
),
COUNT(DISTINCT athlete),
NULL
) as count
FROM `times`
WHERE
team_id = 2 AND time < 19.00;
+-------+
| count |
+-------+
| NULL |
+-------+
was richtig ist, und wenn ich es Texas
für testen, die ich erhalten:
SELECT
IF(
EXISTS(
SELECT 1 FROM times WHERE team_id = 1
),
COUNT(DISTINCT athlete),
NULL
) as count
FROM `times`
WHERE
team_id = 1 AND time < 19.00;
+-------+
| count |
+-------+
| 0 |
+-------+
Es die richtige Antwort gibt.
Aber das Problem ist, dass ich ein sub-query
verwendet, die haben alle Filter der Hauptabfrage zu imitieren mit Ausnahme der time < 19.00
. In meiner realen Anwendung gibt es viel mehr Filter und ich suche nach einer Lösung ohne Unterabfrage.
Eine Sache, die den Sinn kam, war SUM zu verwenden (CASE)
SELECT SUM(CASE
WHEN time < 19.50
THEN 1
ELSE 0
END) as count
FROM `times`
WHERE team_id = 2;
+-------+
| count |
+-------+
| NULL |
+-------+
Das Problem ist, dass dies Zählen mal nicht unterscheidbar Athleten, also für Texas
ich die falsche Zahl erhalten;
SELECT SUM(CASE
WHEN time < 19.50
THEN 1
ELSE 0
END) as count
FROM `times`
WHERE team_id = 1;
+-------+
| count |
+-------+
| 3 |
+-------+
ich 3-mal schneller dass 19.50
statt 1 Athlet schneller als 19.50
.
'19 .50' bekommen, ist eine Zeichenfolge. 19.50 ist eine Zahl – Strawberry
'MySQL' wirft richtig '19 .50 'auf Nummer. Wie auch immer. – Todor