mySQL - 只显示最常见的 & 所有其他列组合显示 0
mySQL - Only display most common & all other column combinations show 0
我正在尝试计算任何汽车在单场比赛中发生的撞车事故的最高次数,因此一辆汽车可能在一场比赛中发生多次撞车事故(比喻)。我遇到了以下列 table 次崩溃:
c_raceName
、c_raceDate
、c_raceId
和其他不相关的。
首先,为了唯一标识一个种族,它出现在 raceName
和 raceDate
对中。要唯一标识崩溃,您必须将这对与 raceId
.
一起使用
所以所有这些列实际上都属于另一个 table,也就是我们的 Entry
table。这个 table 包含了参赛车辆的信息。此 table 包含以下列:
e_raceId
, e_raceDate
, e_raceName
, e_raceEntryCarId
, e_raceEntryDriverId
.
我意识到并不是每场比赛都会进入 Crash
table,所以我相信我要么必须参考 Entry
table 来自Crash
table,或者反过来。
此外,如果尚未包含比赛条目的数据,并且 raceName
和 raceDate
对数据仅存在于 Race
table 上怎么办?其中包含 r_raceName
和 r_raceDate
基本信息。
所以我认为我可能需要做的是 SELECT
从 Crash
table 和 JOIN
到 Entry
table,并进一步进入 Race
table 以真正获得所有 raceName
和 raceDate
对。虽然我不知道我将如何编写一个条件来说明如果这些对不存在于 Crash
table 中,那么在我的输出中我希望它们的值为 0,或者事实上,让它们出现在我的输出中。
所以我已经走到这一步了:
SELECT DISTINCT l.c_raceName AS raceName,
l.c_raceDate AS raceDate,
COUNT( l.c_raceId) AS mostCrashes
FROM Crashes l
GROUP BY l.c_raceId
;
正在生成以下内容的输出:
raceName | raceDate | mostCrashes
---------------------------------
Race 1 |2018/01/21| 1
Race 1 |2018/01/21| 3
... | ... | ...
所以我已经能够将它们分开,如上所示分为 3 和 1,尽管我只希望显示最多的崩溃,所以第 3 行。此外,我希望所有没有发生任何崩溃的比赛都显示为 0,而不是根本不显示。所以我正在寻找的输出是:
raceName | raceDate | mostCrashes
---------------------------------
Race 1 |2018/01/21| 3
Race 2 |2018/01/21| 5
Race 1 |2018/09/11| 0
Race 1 |2016/03/14| 0
等等
请注意,使用 group by
时不需要 select distinct
。
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( * ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
HAVING COUNT( * ) = 0
OR COUNT( *) = (
SELECT
MAX( mostCrashes )
FROM (
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceId ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
) sq
)
ORDER BY
mostCrashes
;
如果您使用 MySQL 8 或更高版本,您可以使用通用 table 表达式 (cte) 来简化它。
WITH cte
AS (
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( * ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
)
SELECT
*
FROM cte
WHERE mostCrashes = ( SELECT MAX( mostCrashes ) FROM cte )
OR mostCrashes = 0
ORDER BY
mostCrashes
;
如果只需要一行,另一种方法是按计算列(降序)对结果进行排序,并将结果限制为一行。 Y
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceId ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
ORDER BY
mostCrashes DESC
LIMIT 1
编辑
CREATE TABLE Crashes(
c_raceName varchar(40) NOT NULL
,c_raceDate varchar(40) NOT NULL
);
✓
INSERT INTO Crashes(c_raceName,c_raceDate)
VALUES
('Race 1','2018/01/21')
, ('Race 1','2018/01/21')
, ('Race 1','2018/01/21')
, ('Race 2','2018/01/21')
, ('Race 2','2018/01/21')
, ('Race 2','2018/01/21')
, ('Race 2','2018/01/21')
, ('Race 2','2018/01/21')
, ('Race 1','2018/09/11')
, ('Race 1','2016/03/14');
;
✓
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceDate ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
HAVING COUNT( l.c_raceDate ) = 0
OR COUNT( l.c_raceDate ) = (
SELECT
MAX( mostCrashes )
FROM (
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceDate ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
) sq
)
ORDER BY
mostCrashes
;
raceName | raceDate | mostCrashes
:------- | :--------- | ----------:
Race 2 | 2018/01/21 | 5
WITH cte
AS (
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceDate ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
)
SELECT
*
FROM cte
WHERE mostCrashes = ( SELECT MAX( mostCrashes ) FROM cte )
OR mostCrashes = 0
ORDER BY
mostCrashes
;
raceName | raceDate | mostCrashes
:------- | :--------- | ----------:
Race 2 | 2018/01/21 | 5
db<>fiddle here
你的问题有多个部分。如果你想要 0
值,那么你需要一个外部连接或相关子查询。我想你在所有比赛中都有一个 table,但是 entries
table 上的 select distinct
也可以。
然后,如果您希望每辆车发生最多车祸,您需要 car crashes
table 中的标识符].我确定那里有一个(这很有意义),但是您没有在问题中描述它。我猜它类似于 c_raceEntryCarId
.
生成的查询如下所示:
select e_racename, e.e_racedate,
(select count(*)
from crashes c
where c.c_racename = e.e_racename and c.e_racedate = e.e_race_date
group by c.c_raceEntryCarId
order by count(*) desc
limit 1
) as most_crashes
from (select e.e_racename, e.e_racedate
from entries e
group by e.e_racename, e.e_racedate
) e;
如果您只想要每场比赛的撞车次数,则子查询会有些不同:
select e_racename, e.e_racedate,
(select count(*)
from crashes c
where c.c_racename = e.e_racename and c.e_racedate = e.e_race_date
) as most_crashes
from (select e.e_racename, e.e_racedate
from entries e
group by e.e_racename, e.e_racedate
) e;
我正在尝试计算任何汽车在单场比赛中发生的撞车事故的最高次数,因此一辆汽车可能在一场比赛中发生多次撞车事故(比喻)。我遇到了以下列 table 次崩溃:
c_raceName
、c_raceDate
、c_raceId
和其他不相关的。
首先,为了唯一标识一个种族,它出现在 raceName
和 raceDate
对中。要唯一标识崩溃,您必须将这对与 raceId
.
所以所有这些列实际上都属于另一个 table,也就是我们的 Entry
table。这个 table 包含了参赛车辆的信息。此 table 包含以下列:
e_raceId
, e_raceDate
, e_raceName
, e_raceEntryCarId
, e_raceEntryDriverId
.
我意识到并不是每场比赛都会进入 Crash
table,所以我相信我要么必须参考 Entry
table 来自Crash
table,或者反过来。
此外,如果尚未包含比赛条目的数据,并且 raceName
和 raceDate
对数据仅存在于 Race
table 上怎么办?其中包含 r_raceName
和 r_raceDate
基本信息。
所以我认为我可能需要做的是 SELECT
从 Crash
table 和 JOIN
到 Entry
table,并进一步进入 Race
table 以真正获得所有 raceName
和 raceDate
对。虽然我不知道我将如何编写一个条件来说明如果这些对不存在于 Crash
table 中,那么在我的输出中我希望它们的值为 0,或者事实上,让它们出现在我的输出中。
所以我已经走到这一步了:
SELECT DISTINCT l.c_raceName AS raceName,
l.c_raceDate AS raceDate,
COUNT( l.c_raceId) AS mostCrashes
FROM Crashes l
GROUP BY l.c_raceId
;
正在生成以下内容的输出:
raceName | raceDate | mostCrashes
---------------------------------
Race 1 |2018/01/21| 1
Race 1 |2018/01/21| 3
... | ... | ...
所以我已经能够将它们分开,如上所示分为 3 和 1,尽管我只希望显示最多的崩溃,所以第 3 行。此外,我希望所有没有发生任何崩溃的比赛都显示为 0,而不是根本不显示。所以我正在寻找的输出是:
raceName | raceDate | mostCrashes
---------------------------------
Race 1 |2018/01/21| 3
Race 2 |2018/01/21| 5
Race 1 |2018/09/11| 0
Race 1 |2016/03/14| 0
等等
请注意,使用 group by
时不需要 select distinct
。
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( * ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
HAVING COUNT( * ) = 0
OR COUNT( *) = (
SELECT
MAX( mostCrashes )
FROM (
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceId ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
) sq
)
ORDER BY
mostCrashes
;
如果您使用 MySQL 8 或更高版本,您可以使用通用 table 表达式 (cte) 来简化它。
WITH cte
AS (
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( * ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
)
SELECT
*
FROM cte
WHERE mostCrashes = ( SELECT MAX( mostCrashes ) FROM cte )
OR mostCrashes = 0
ORDER BY
mostCrashes
;
如果只需要一行,另一种方法是按计算列(降序)对结果进行排序,并将结果限制为一行。 Y
SELECT
l.c_raceName AS raceName
, l.c_raceDate AS raceDate
, COUNT( l.c_raceId ) AS mostCrashes
FROM Crashes l
GROUP BY
l.c_raceName
, l.c_raceDate
ORDER BY
mostCrashes DESC
LIMIT 1
编辑
CREATE TABLE Crashes( c_raceName varchar(40) NOT NULL ,c_raceDate varchar(40) NOT NULL );
✓
INSERT INTO Crashes(c_raceName,c_raceDate) VALUES ('Race 1','2018/01/21') , ('Race 1','2018/01/21') , ('Race 1','2018/01/21') , ('Race 2','2018/01/21') , ('Race 2','2018/01/21') , ('Race 2','2018/01/21') , ('Race 2','2018/01/21') , ('Race 2','2018/01/21') , ('Race 1','2018/09/11') , ('Race 1','2016/03/14'); ;
✓
SELECT l.c_raceName AS raceName , l.c_raceDate AS raceDate , COUNT( l.c_raceDate ) AS mostCrashes FROM Crashes l GROUP BY l.c_raceName , l.c_raceDate HAVING COUNT( l.c_raceDate ) = 0 OR COUNT( l.c_raceDate ) = ( SELECT MAX( mostCrashes ) FROM ( SELECT l.c_raceName AS raceName , l.c_raceDate AS raceDate , COUNT( l.c_raceDate ) AS mostCrashes FROM Crashes l GROUP BY l.c_raceName , l.c_raceDate ) sq ) ORDER BY mostCrashes ;
raceName | raceDate | mostCrashes :------- | :--------- | ----------: Race 2 | 2018/01/21 | 5
WITH cte AS ( SELECT l.c_raceName AS raceName , l.c_raceDate AS raceDate , COUNT( l.c_raceDate ) AS mostCrashes FROM Crashes l GROUP BY l.c_raceName , l.c_raceDate ) SELECT * FROM cte WHERE mostCrashes = ( SELECT MAX( mostCrashes ) FROM cte ) OR mostCrashes = 0 ORDER BY mostCrashes ;
raceName | raceDate | mostCrashes :------- | :--------- | ----------: Race 2 | 2018/01/21 | 5
db<>fiddle here
你的问题有多个部分。如果你想要 0
值,那么你需要一个外部连接或相关子查询。我想你在所有比赛中都有一个 table,但是 entries
table 上的 select distinct
也可以。
然后,如果您希望每辆车发生最多车祸,您需要 car crashes
table 中的标识符].我确定那里有一个(这很有意义),但是您没有在问题中描述它。我猜它类似于 c_raceEntryCarId
.
生成的查询如下所示:
select e_racename, e.e_racedate,
(select count(*)
from crashes c
where c.c_racename = e.e_racename and c.e_racedate = e.e_race_date
group by c.c_raceEntryCarId
order by count(*) desc
limit 1
) as most_crashes
from (select e.e_racename, e.e_racedate
from entries e
group by e.e_racename, e.e_racedate
) e;
如果您只想要每场比赛的撞车次数,则子查询会有些不同:
select e_racename, e.e_racedate,
(select count(*)
from crashes c
where c.c_racename = e.e_racename and c.e_racedate = e.e_race_date
) as most_crashes
from (select e.e_racename, e.e_racedate
from entries e
group by e.e_racename, e.e_racedate
) e;