需要编写一个查询而不是 5 个查询来获得所有 5 个状态的结果

Posted

技术标签:

【中文标题】需要编写一个查询而不是 5 个查询来获得所有 5 个状态的结果【英文标题】:Need to write a query instead of 5 queries to get the result of all 5 states 【发布时间】:2020-12-02 19:29:18 【问题描述】:

CSV 文件有大约 62000 行,它有州和县(县名在该特定州内是唯一的)。

我必须在视图上编写 5 个查询。每个查询都会为其中一个州检索 State_Name、Date、MAX(SumConfirmed) 每个州确诊病例数最多的日期。

SELECT State_Name, Date, ConfirmedCases AS Max_ConfirmedCases
FROM covid_by_state
WHERE ConfirmedCases =
    (SELECT max(ConfirmedCases) AS Max_ConfirmedCases
     FROM covid_by_state
     WHERE State_Name='Texas');

上述查询为我提供了一个特定状态的结果,但我无法找到如何在一个查询中获得 5 个状态的结果。

【问题讨论】:

这是我创建的视图 CREATE VIEW COVID_BY_STATE AS SELECT Date, State_Name, Sum(Daily_Count_Cases) as ConfirmedCases, Sum(Daily_Deaths) as DailyDeath FROM Covid_By_County GROUP BY Date, State_Name; STATE TABEL CREATE TABLE state (State_Name VARCHAR(50), State_Cap_City VARCHAR(50), PRIMARY KEY (State_Name)); COUNTY TABLE CREATE TABLE 县(County_Name VARCHAR(50), State_Name VARCHAR(50), FOREIGN KEY (State_Name) REFERENCES state (State_Name), PRIMARY KEY (County_Name, State_Name)); 【参考方案1】:

我正在跳过使用视图;我不认为它在可读性方面增加了任何价值,如果您想开始将查询限制在某个日期范围或添加其他条件,它将无法工作。

select
    State_Name,
    max_confirmed_cases_date as Date,
    max(ConfirmedCases) as Max_ConfirmedCases
from (
    select
        State_Name,
        first_value(Date) over (partition by State_Name order by ConfirmedCases desc, Date) max_confirmed_cases_date, 
        ConfirmedCases
    from (
        select Date, State_Name, sum(Daily_Count_Cases) ConfirmedCases
        from Covid_By_County
        group by Date, State_Name
    ) daily_state_totals
) daily_state_totals_with_max_cases_date
group by State_Name, max_confirmed_cases_date

最里面的子选择相当于你的视图;每个日期每个州都有一行,总共有案例。中间的子选择重复其中的每一行,但不是使用日期,而是使用 first_value() 来查找具有最高案例数的该州的日期(在平局的情况下,更喜欢较早的日期而不是较晚的日期)。然后外部选择将其减少到每个状态一行。

或者,如果您使用的是不支持窗口功能的旧版本:

select
    State_Name,
    date(substr(min(concat(99999999999-ConfirmedCases,Date)),12)) as Date,
    max(ConfirmedCases) as Max_ConfirmedCases
from (
    select Date, State_Name, sum(Daily_Count_Cases) ConfirmedCases
    from Covid_By_County
    group by Date, State_Name
) daily_state_totals
group by State_Name

此查询使用一种技巧,通过获取编码案例和日期的字符串的最小值来获取每个州的最大案例日期。

【讨论】:

【参考方案2】:

我想你想要一个 correlated 子查询:

SELECT cbs.State_Name, cbs.Date, cbs.ConfirmedCases as Max_ConfirmedCases
FROM covid_by_state cbs
WHERE cbs.ConfirmedCases = (SELECT max(cbs2.ConfirmedCases) 
                            FROM covid_by_state cbs2
                            WHERE cbs2.State_Name = cbs.State_Name
                           );

这会同时返回所有个状态的行。

编辑:

如果您希望所有日期都具有特定状态的最大值,那么您可以使用聚合:

SELECT cbs.State_Name, GROUP_CONCAT(cbs.Date) as dates,
       cbs.ConfirmedCases as Max_ConfirmedCases
FROM covid_by_state cbs
WHERE cbs.ConfirmedCases = (SELECT max(cbs2.ConfirmedCases) 
                            FROM covid_by_state cbs2
                            WHERE cbs2.State_Name = cbs.State_Name
                           )
GROUP BY cbs.State_Name, cbs.ConfirmedCases

【讨论】:

我认为如果两个州的最大 ConfirmedCases 相同,这(以及提问者的原始答案)无法正常工作 为避免重复,请参阅 mysql.rjweb.org/doc.php/groupwise_max 中的一些解决方案 @ysth 。 . . OP 不清楚在这种情况下该怎么做。鉴于现有查询返回的 any 状态的行,其事例数与特定状态的最大值匹配,这绝对是一个改进。

以上是关于需要编写一个查询而不是 5 个查询来获得所有 5 个状态的结果的主要内容,如果未能解决你的问题,请参考以下文章

2023-01-03:超过5名学生的课。编写一个SQL查询来报告 至少有5个学生 的所有班级,返回结果不限顺序。请问sql语句如何写? +---------+ | class | +-----

如何编写/优化需要从 6 个相关表中选择数据的 sql 查询,直到获得所需的数据

APEX初步 [5] —— SOQL查询

我如何才能获得公司平均工资不到 5 年的所有员工

核心数据查询,每年最近的汽车?

在 MySQL 中,如何编写 SQL 来连接两个表而不是一个子查询?