社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

mysql-仅显示最常见的列组合&所有其他列组合显示0

bemzoo • 6 年前 • 1709 次点击  

我试图计算出一场比赛中撞车次数最多的一辆车,所以一辆车在一场比赛中可能会发生多起撞车事故(形象地说)。我有一个包含以下列的崩溃表:

c_raceName , c_raceDate , c_raceId 以及其他不相关的事情。

首先,为了唯一地识别一个种族 raceName raceDate 一对。要唯一识别崩溃,必须在 raceId .

所以所有这些列实际上都属于另一个表 Entry 表。此表包含参加比赛的汽车的信息。此表包含以下列:

e_raceId , e_raceDate , e_raceName , e_raceEntryCarId , e_raceEntryDriverId .

我意识到并不是每一场比赛都会参加 Crash 桌子,所以我想我要提到 条目 中的表 撞车 桌子,或者其他地方。

尽管如此,如果还没有包含比赛项目的数据呢? raceNAMEY 赛马场 一对数据只存在于 Race 放置 r_raceName r_raceDate 基本信息。

所以我想我应该做的是 SELECT 撞车 表,以及 JOIN 下到 条目 桌子,再往前 种族 真正得到一切的桌子 raceNAMEY 赛马场 对。尽管我不知道如何写一个条件,如果这些对不存在于 撞车 表,那么在我的输出中,我希望它们被赋予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

等。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43517
 
1709 次点击  
文章 [ 2 ]  |  最新文章 6 年前
Used_By_Already
Reply   •   1 楼
Used_By_Already    6 年前

请注意你不需要 select distinct 使用时 group by .

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或更高版本,那么可以使用公共表表达式(common table expression,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
;
总状花序总状花序多数
:———————————————————
比赛2 2018/01/21 5

DB<gt;小提琴 here

Gordon Linoff
Reply   •   2 楼
Gordon Linoff    6 年前

你的问题有多个部分。如果你想要 0 值,则需要外部联接或相关子查询。我想你有一张所有比赛的桌子,但是 select distinct entries 桌子也能用。

如果你想让大多数人崩溃 每辆车 你需要一个 汽车 中的标识符 crashes 表。我肯定有一个(这很有道理),但你不会在问题中描述它。我猜大概是 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;