【问题标题】:Query to select row with first occurrence of an element查询以选择第一次出现元素的行
【发布时间】:2021-07-25 05:15:01
【问题描述】:

我正在尝试编译的一些数据中有以下 SQL 查询:

SELECT State, CountyName, Month, SUM(Sum_Confirmed) AS Max_Sum_Confirmed 
FROM `covid_by_countynmonth` 
GROUP BY State, Month 
ORDER BY State, Max_Sum_Confirmed DESC 

它给了我下表:

我怎样才能让它只显示每个州的第一条记录?

我想要这样的东西(我是通过添加 WHERE Month="July" 得到的,但这只是为了这个例子):

【问题讨论】:

  • 可能最好的答案是使用Window Function,但这需要您使用 MySQL 8.0。你是吗?
  • 请分享更多详细信息,例如表结构、示例输入数据、预期输出数据和您解决问题的尝试,以及所有可读形式(即文本)
  • @turing042 - 您是否希望在等待结果或状态总和中仅从第一个月(如 21502)开始有 Max_Sum_Confirmed
  • @BerndBuffen 是的,我只想从第一个月开始显示
  • @turing042。 . .您的查询格式不正确,因为 CountyName 既不在 GROUP BY 中,也不是聚合函数的参数。

标签: mysql sql database greatest-n-per-group


【解决方案1】:

我怎样才能让它只显示每个州的第一条记录?

使用窗口函数:

SELECT sm.*
FROM (SELECT State, Month,
             SUM(Sum_Confirmed) AS Max_Sum_Confirmed,
             ROW_NUMBER() OVER (PARTITION BY State ORDER BY SUM(SUM_Confirmed) DESC) as seqnum
      FROM `covid_by_countynmonth` 
      GROUP BY State, Month 
     ) sm
WHERE seqnum = 1;
ORDER BY State, Max_Sum_Confirmed DESC ;

CountyName 似乎是多余的所以我删除了它。

【讨论】:

    【解决方案2】:

    这是一个包含两个输出的示例:来自月份的值和来自州的 SUM

    SELECT
        c.State , c.CountyName
        , MONTHNAME(minMonth) as 'Month'
        , c.Sum_Confirmed -- SUM othe State der
        , f.Sum_Confirmed -- only from the first Month
          FROM (
          SELECT
              State, CountyName
            , MIN(str_to_date(`Month`,'%M')) as minMonth
            , SUM(Sum_Confirmed) as Sum_Confirmed
          FROM covid_by_countynmonth
          GROUP BY State
        ) AS c
    LEFT JOIN covid_by_countynmonth AS f ON c.State = f.State AND f.`Month` = MONTHNAME(minMonth);
    

    样本

    MariaDB [Bernd]> SELECT * FROM covid_by_countynmonth;
    +----+-------+------------+---------+---------------+
    | id | State | CountyName | Month   | Sum_Confirmed |
    +----+-------+------------+---------+---------------+
    |  1 | AR    | Arkansas   | July    |         21502 |
    |  2 | AR    | Arkansas   | June    |         13244 |
    |  3 | LA    | Acadia     | July    |         40500 |
    |  4 | LA    | Acadia     | May     |         11997 |
    |  5 | LA    | Acadia     | January |           999 |
    +----+-------+------------+---------+---------------+
    5 rows in set (0.10 sec)
    
    MariaDB [Bernd]> SELECT
        -> c.State , c.CountyName
        -> , MONTHNAME(minMonth) as 'Month'
        -> , c.Sum_Confirmed -- SUM othe State der
        -> , f.Sum_Confirmed -- only from the first Month
        ->   FROM (
        ->   SELECT
        ->       State, CountyName
        ->     , MIN(str_to_date(`Month`,'%M')) as minMonth
        ->     , SUM(Sum_Confirmed) as Sum_Confirmed
        ->   FROM covid_by_countynmonth
        ->   GROUP BY State
        -> ) AS c
        -> LEFT JOIN covid_by_countynmonth AS f ON c.State = f.State AND f.`Month` = MONTHNAME(minMonth);
    +-------+------------+---------+---------------+---------------+
    | State | CountyName | Month   | Sum_Confirmed | Sum_Confirmed |
    +-------+------------+---------+---------------+---------------+
    | AR    | Arkansas   | June    |         34746 |         13244 |
    | LA    | Acadia     | January |         53496 |           999 |
    +-------+------------+---------+---------------+---------------+
    2 rows in set (0.05 sec)
    
    MariaDB [Bernd]> 
    

    【讨论】:

      【解决方案3】:

      显然这只适用于 postgresql。

      使用 DISTINCT ON 来选择不同的值,如下所示:

      SELECT DISTINCT ON (COLUMN_OF_INTEREST) COLUMN_ALIAS, ...
      

      然后与初始查询变成这样:

      SELECT DISTINCT ON (SUB_.State) SUB_.State, SUB_.Month, SUB_.Max_Sum_Confirmed 
      FROM (SELECT State, Month, SUM(Sum_Confirmed) AS Max_Sum_Confirmed 
      FROM `covid_by_countynmonth` 
      GROUP BY State, Month) AS SUB_ ORDER BY SUB_.State, SUB_.Max_Sum_Confirmed DESC
      

      【讨论】:

      • 你不能用 DISTINCT 获得第一行
      • @BerndBuffen 这不是第一行,可以得到limit = 1的第一行,这是特定值的第一条记录
      • 不,您还必须给出一个 ORDER BY ,否则无法保证结果,并且在此示例中,顺序是月份名称。所以他必须使用 month(str_to_date(Month,'%b')) 来订购它
      猜你喜欢
      • 2015-06-15
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 2010-09-11
      • 2011-06-05
      • 2015-11-04
      • 1970-01-01
      • 2011-03-09
      相关资源
      最近更新 更多