力扣-Mysql-3328-查找每个州的城市 II(中等)

一、题目来源

3328. 查找每个州的城市 II - 力扣(LeetCode)

二、数据表结构

表:cities

复制代码
+-------------+---------+
| Column Name | Type    | 
+-------------+---------+
| state       | varchar |
| city        | varchar |
+-------------+---------+
(state, city) 是这张表中值互不相同的列的组合。
这张表的每一行包含州名和其中的城市名。

三、需求

编写一个解决方案来找到 每个州 中的 所有城市 并且根据下列条件分析它们:

  • 逗号分隔 字符串组合每一个州的所有城市。
  • 只显示有 至少 3 个城市的州。
  • 只显示 至少有一个城市 以与 州名相同字母开头 的州。

返回结果表以字母匹配城市的数量 降序 排序,然后按州名称 升序 排序的结果表。

四、示例数据

输入:

cities 表:

复制代码
+--------------+---------------+
| state        | city          |
+--------------+---------------+
| New York     | New York City |
| New York     | Newark        |
| New York     | Buffalo       |
| New York     | Rochester     |
| California   | San Francisco |
| California   | Sacramento    |
| California   | San Diego     |
| California   | Los Angeles   |
| Texas        | Tyler         |
| Texas        | Temple        |
| Texas        | Taylor        |
| Texas        | Dallas        |
| Pennsylvania | Philadelphia  |
| Pennsylvania | Pittsburgh    |
| Pennsylvania | Pottstown     |
+--------------+---------------+

输出:

复制代码
+-------------+-------------------------------------------+-----------------------+
| state       | cities                                    | matching_letter_count |
+-------------+-------------------------------------------+-----------------------+
| Pennsylvania| Philadelphia, Pittsburgh, Pottstown       | 3                     |
| Texas       | Dallas, Taylor, Temple, Tyler             | 3                     |
| New York    | Buffalo, Newark, New York City, Rochester | 2                     |
+-------------+-------------------------------------------+-----------------------+

解释:

  • Pennsylvania :
    • 有 3 个城市(符合最低条件)
    • 所有的 3 个城市都以 'P' 开头(与州相同)
    • matching_letter_count = 3
  • Texas :
    • 有 4 个城市(符合最低条件)
    • 3 个城市 (Taylor, Temple, Tyler) 以 'T' 开头(与州相同)
    • matching_letter_count = 3
  • New York :
    • 有 4 个城市(符合最低条件)
    • 2 个城市 (Newark, New York City) 以 'N' 开头(与州相同)
    • matching_letter_count = 2
  • California 没有包含在输出表,因为:
    • 尽管它有 4 个城市(符合最低条件)
    • 没有城市以 'C' 开头(不符合字母匹配条件)
  • 注意:
  • 结果以 matching_letter_count 降序排序。
  • 当 matching_letter_count 持平(Texas 和 New York 都为 2),按州名字母序排序。
  • 每一行的城市也以字母序排序。

五、分析

1.文字分析

第一步:首先使用group_concat函数将每个州的城市使用逗号连接,并统计每个州的城市数量;

第二步:使用 left 获取城市名和州名的首字母,让它们相同,并统计城市名首字母和州名首字母相同的城市数量;

第三步:连接前两步得到的表,进行最终筛选,使cnt1>=3, cnt2>=1,cnt2即为所有的matching_letter_count,最终再根据m_l_c 降序, 州名升序进行排列。

2.图解

六、代码实现

sql 复制代码
with t1 AS (
    SELECT
        state,
        group_concat(city order by city SEPARATOR ', ') as cities,
        COUNT(city) cnt1
    FROM cities
    GROUP BY state
),t2 as(
    select
        state,
        count(city) as cnt2
    from cities
    where left(city,1) = left(state,1)
    group by state
)
SELECT
    distinct
    t1.state,
    t1.cities,
    cnt2 as matching_letter_count
from t1,t2
where t1.state = t2.state and cnt1 >= 3 and cnt2 >= 1
ORDER BY matching_letter_count desc ,t1.state;

七、总结

本题需求为查询每个州的城市:

难点在于将每个州原本是列数据的城市,使用逗号分隔为一行数据输出。我们使用了 Group_Concat 聚合函数解决这个问题;

Group_Concat 函数是一个聚合函数,它可以将分组后的某一列的值按照指定的分隔符连接成一个字符串。在一些情况下,我们可以利用它来将多列的数据转换为一行中的字符串形式,虽然不是严格意义上的列转行,但在某些展示场景下是很有用的。

获取每个州以及城市的首字母使用了 Left 函数;

Left() 函数是一个用于字符串操作的函数。它的主要功能是从一个字符串的左边开始提取指定长度的子字符串,基本语法为 :Left(str , length)。其中str是要操作的原始字符串,length是要从左边提取的子字符串的长度。

相关推荐
随心Coding12 分钟前
【MySQL】存储引擎有哪些?区别是什么?
数据库·mysql
羊小猪~~4 小时前
MYSQL学习笔记(四):多表关系、多表查询(交叉连接、内连接、外连接、自连接)、七种JSONS、集合
数据库·笔记·后端·sql·学习·mysql·考研
小孟Java攻城狮4 小时前
leetcode-不同路径问题
算法·leetcode·职场和发展
查理零世4 小时前
算法竞赛之差分进阶——等差数列差分 python
python·算法·差分
小猿_007 小时前
C语言程序设计十大排序—插入排序
c语言·算法·排序算法
苹果醋37 小时前
golang 编程规范 - Effective Go 中文
java·运维·spring boot·mysql·nginx
暮湫7 小时前
MySQL(1)概述
数据库·mysql
叫我:松哥8 小时前
基于Python django的音乐用户偏好分析及可视化系统设计与实现
人工智能·后端·python·mysql·数据分析·django
熊文豪9 小时前
深入解析人工智能中的协同过滤算法及其在推荐系统中的应用与优化
人工智能·算法
siy233311 小时前
[c语言日寄]结构体的使用及其拓展
c语言·开发语言·笔记·学习·算法