MySQL - 不同月份的最大总和与多年的关系

Vér*_*ace 10 mysql-5.6

对此问题予以启发这一个(闭合)和几乎是相同的这一个,但使用不同的RDBMS(PostgreSQL的对比的MySQL)。

假设我有一个肿瘤列表(这个数据是根据真实数据模拟的):

CREATE table illness (nature_of_illness VARCHAR(25), created_at DATETIME);

INSERT INTO illness VALUES ('Cervix', '2018-01-03 15:45:40');
INSERT INTO illness VALUES ('Cervix', '2018-01-03 15:45:40');
INSERT INTO illness VALUES ('Cervix', '2018-01-03 15:45:40');
INSERT INTO illness VALUES ('Cervix', '2018-01-03 15:45:40');
INSERT INTO illness VALUES ('Cervix', '2018-01-03 15:45:40');
INSERT INTO illness VALUES ('Lung',   '2018-01-03 17:50:32');
INSERT INTO illness VALUES ('Lung',   '2018-02-03 17:50:32');
INSERT INTO illness VALUES ('Lung',   '2018-02-03 17:50:32');
INSERT INTO illness VALUES ('Lung',   '2018-02-03 17:50:32');
INSERT INTO illness VALUES ('Cervix', '2018-02-03 17:50:32');
-- 2017, with 1 Cervix and Lung each for the month of Jan - tie!
INSERT INTO illness VALUES ('Cervix', '2017-01-03 15:45:40');
INSERT INTO illness VALUES ('Lung',   '2017-01-03 17:50:32');
INSERT INTO illness VALUES ('Lung',   '2017-02-03 17:50:32');
INSERT INTO illness VALUES ('Lung',   '2017-02-03 17:50:32');
INSERT INTO illness VALUES ('Lung',   '2017-02-03 17:50:32');
INSERT INTO illness VALUES ('Cervix', '2017-02-03 17:50:32');
Run Code Online (Sandbox Code Playgroud)

您想找出在给定月份中哪个特定肿瘤最常见 - 到目前为止一切顺利!

现在,您会注意到,对于 2017 年的第 1 个月,存在平局 - 因此随机选择一个并给出答案是没有意义的- 因此必须包括平局- 这使问题更具挑战性。

正确答案是:

  Year    Month  Tumour count      Type
  2017        1             1    Cervix  -- note tie
  2017        1             1      Lung  --   "   "
  2017        2             3      Lung
  2018        1             5    Cervix
  2018        2             3      Lung
Run Code Online (Sandbox Code Playgroud)

另一个好处是将月份名称显示为文本而不是整数。

我有一个解决方案,但它非常复杂 - 我想知道我的解决方案是否最佳。MySQL小提琴在这里

Vér*_*ace 5

我试图解决这个问题如下。我将不胜感激有关如何改进此查询的任何建议:

SELECT 
  t3.c_year AS "Year",
  t3.c_month AS "Month", 
  t3.il_mc AS  "Tumour count", 
  t4.ill_nat AS "Type" FROM
(
  SELECT c_year, c_month, il_mc FROM
  (
    SELECT  
    c_year, 
    c_month,
    MAX(month_count) AS il_mc
  FROM
    (
      SELECT nature_of_illness as illness,
        EXTRACT(YEAR  FROM created_at) AS c_year,
        EXTRACT(MONTH FROM created_at) AS c_month,
        COUNT(EXTRACT(MONTH FROM created_at)) AS month_count
      FROM illness
      GROUP BY illness, c_year, c_month
      ORDER BY c_year, c_month
    ) AS t1
  GROUP BY c_year, c_month
  ) AS t2
) AS t3
JOIN
(
SELECT 
  EXTRACT(YEAR FROM created_at) AS t_year, 
  EXTRACT(MONTH FROM created_at) AS t_month,  
  nature_of_illness AS ill_nat, 
  COUNT(nature_of_illness) AS ill_cnt
FROM illness
GROUP BY t_year, t_month, nature_of_illness
ORDER BY t_year, t_month, nature_of_illness
) AS t4
ON t3.c_year = t4.t_year
AND t3.c_month = t4.t_month
AND t3.il_mc = t4.ill_cnt
Run Code Online (Sandbox Code Playgroud)

它确实给出了正确的结果,正如在这里的小提琴中所见!