MySQL查询:查询一个表中类别字段中Max()最大值对应的记录

本文介绍了一种在MySQL中查询每个类别点击量最大记录的方法,并提供了解决自连接查询导致MySQL服务停止问题的方案。

转:https://my.oschina.net/hanzhankang/blog/210623

 问题是:

数据库有一个表 code,里面有个点击量字段click_num和一个类别字段kind以及其它信息字段,

现在要搜出每个类别中点击量最大的那条记录,如果是10个类别,那么结果应该是10条记录,

如果最大点击量有两个相同的只要一条。

经过N次搜索,N次检测网上的解决SQL语句,终于找到个优雅的而且结果正确的SQL,这个是一个博客作者在Mysql的官方文档里面发现的。

禁不住收藏了,以备后用。

select id,kind,click_num from code as a   
where  click_num=(select max(b.click_num)  
    from code as b  
    where a.kind = b.kind  
); 

特别注意:

这个语句在SQLite上测试正常,速度很快。但是在我机器上的MySql5.0上执行后就死机了,其他版本的Mysql不知道什么情况。

上面的语句还不能满足我的第二个要求就是:如果某类别中最大点击量有两个相同的记录,只要一条。

下面是我附加的解决办法:

筛选,保证每个类别只有一条,(kind,id改为所有列,结果就是对应的记录了)

select  *   
from (select id,kind,click_num from code as a
    where  click_num=(select max(b.click_num)  
        from code as b  
        where a.kind = b.kind  
        )  
    ) as a  
group by kind  

后续:

结合以往的Mysql使用经验发现Mysql的一个最大问题就是在一个查询的where子句中如果包含对前面select的表的查询那么CPU占用就会飙升Mysql服务停止。可以说是自连接查询问题,不知道这是不是个bug,5.0,5.1版本都有这个问题,回头看看上面的SQL语句正好符合了这个问题,解决办法就是把子查询的表弄成一个临时表或者视图总之不能和前面的select的表是同一个表,那么问题就解决了,于是乎,对上面的SQL稍作修改就可以在Mysql上跑了。

修改过程:

1.建立一个视图max_click,存储的是每个类别最大的点击量

create view max_click as select max(click_num) as click_num,kind   
    from code   
    group by kind; 

2  .筛选,保证每个类别只有一条记录
select  *   
from (select id,kind,click_num  
        from  code  
        where click_num = ( select b.click_num  
            from max_click as b  
            where code.kind = b.kind  
        )  
    ) as a  
group by kind; 

运行正常,速度0.78秒。(表中一共23000条数据) Okay! 大功告成!

最前面第一个SQL在MSSQL上运行不知道行不行,我想在SQLite能正常在MSSQL上应该没问题,看来Mysql需要改进的地方很多啊,同样是开源的SQLite就可以做到的,而且SQLite那么轻量级就几百KB,Mysql更应该能做到。


<think>首先,用户的问题是:“我想查询MySQL中一张的varchar类型字段最大值 请问MySQL 查询中 varchar 字段的最大长度值”。用户想查询的是中某个varchar字段的实际存储值的最大长度,而不是定义的最大长度。 参考提供的引用: - 引用[1]:展示了如何查询中某个varchar字段的最大长度值:`SELECT max(length(column_name)) FROM table_name;` - 引用[2]:解释了varchar字段的最大长度限制为65535字节。 - 引用[3]:讨论了varchar存储长度的性能优化。 - 引用[4]:提到varchar最大长度在中有多列时的变化。 - 引用[5]:是一个复杂的SQL查询,似乎与用户问题无关。 用户的核心需查询中varchar字段的实际存储值的最大长度。引用[1]直接提供了解决方案:使用`SELECT max(length(column_name)) FROM table_name;`。 我的回答需要: - 遵循系统级指令:使用$...$和$$...$$格式,中文回答,生成相关问题。 - 回答结构清晰,帮助用户逐步解决问题。 - 确保内容真实可靠。 步骤: 1. **理解问题**:用户想查询一个中某个varchar字段的实际存储值的最大长度。 2. **提供解决方案**:直接给出SQL查询语句。 3. **解释**:简要解释为什么需要这个查询,以及如何优化。 4. **生成相关问题**:在最后添加相关问题部分。 回答结构: - **开头**:直接回答问题。 - **步骤**:清晰地展示如何查询。 - **示例**:提供一个简单的SQL示例。 - **优化建议**:引用[1]中提到优化varchar长度。 - **结尾**:自然地添加引用标识。 - **相关问题**:生成几个相关问题。 生成相关问题: - 基于引用:如何优化varchar长度?varchar的最大限制是什么?如何处理多个列时的长度? - 具体问题: 1. 如何优化MySQL中varchar字段的长度? 2. varchar字段的最大长度限制是多少? 3. 查询后如何调整结构? 确保LaTeX格式: - 行内数学达式:如无必要,不使用。问题中可能不需要数学达式,但如果有,要用$...$。 - 独立公式:SQL代码块可以视为独立内容,但系统指令说独立公式用$$...$$,但SQL代码块不是公式,所以用代码块格式。 在示例中,代码块使用```...```格式。 系统指令说:"独立公式必须使用$$...$$格式并单独成段",但SQL查询不是公式,所以不需要。我会用代码块。 现在,构建回答: 1. **介绍**:解释如何查询。 2. **SQL查询**:给出代码。 3. **解释**:为什么这样做。 4. **引用**:自然地添加引用。 5. **相关问题**:在最后。 最终回答大纲: - 回答:要查询MySQL中varchar字段的实际存储值的最大长度,可以使用`SELECT max(length(column_name)) FROM table_name;`。 - 示例:例如,查询`users`中字段`username`的最大长度。 - 优化建议:基于引用[1],查询后可以优化字段长度。 - 引用:在相关部分添加[^1]。 - 相关问题:列出3-4个。 相关问题: 1. 如何优化MySQL中varchar字段的长度? 2. varchar字段的最大长度限制是多少? 3. 查询后如何调整结构? 4. 在中有多列时,varchar长度如何影响性能? 引用标识: - 引用[1]:在解释优化时添加。 - 引用[2]:在讨论最大长度限制时添加。 - 但用户问题主要是查询,所以引用[1]最相关。 确保回答真实可靠:查询语句是标准的MySQL语法。</think>### 查询MySQL中varchar字段的最大长度值 在MySQL中,查询中某个varchar类型字段的实际存储值(非定义长度)的最大长度,是一个常见的优化需。这有助于了解数据分布,并为后续调整字段长度提供依据。以下是详细步骤和解释: #### 步骤1: 使用SQL查询最大长度 要查询中特定varchar字段的实际存储值的最大长度,可以使用MySQL内置函数 `LENGTH()` 和 `MAX()`。基本语法如下: ```sql SELECT MAX(LENGTH(column_name)) AS max_length FROM table_name; ``` - **`LENGTH(column_name)`**: 计算字段中每个值的字节长度(对于多字节字符集如UTF-8,需注意字符与字节的差异)。 - **`MAX()`**: 返回这些长度中的最大值。 - **结果**: 查询会返回一个整数,示该字段中所有行的最大存储长度。 例如,查询 `users` 中字段 `username` 的最大长度: ```sql SELECT MAX(LENGTH(username)) AS max_username_length FROM users; ``` #### 步骤2: 考虑字符集的影响 - 如果使用多字节字符集(如UTF-8),一个字符可能占用多个字节。此时,`LENGTH()` 返回字节长度,而 `CHAR_LENGTH()` 返回字符长度。根据需选择: - 字节长度:`SELECT MAX(LENGTH(column_name)) FROM table_name;` - 字符长度:`SELECT MAX(CHAR_LENGTH(column_name)) FROM table_name;` - 示例(UTF-8字符集): ```sql -- 查询字节长度最大值 SELECT MAX(LENGTH(username)) AS max_byte_length FROM users; -- 查询字符长度最大值 SELECT MAX(CHAR_LENGTH(username)) AS max_char_length FROM users; ``` #### 步骤3: 优化建议 查询后,如果发现最大长度远小于字段定义的长度(如定义 `VARCHAR(255)` 但实际最大长度只有50),可以优化结构以减少存储空间并提升性能: - **缩短字段长度**:使用 `ALTER TABLE` 修改字段定义。例如: ```sql ALTER TABLE users MODIFY username VARCHAR(50); ``` - **原则**:尽量将字段长度设置为略大于实际最大值(如最大值50,则设置为 `VARCHAR(60)`),避免未来数据扩展问题。如果定义过长,会浪费存储并降低查询效率;定义过短可能导致数据截断[^1]。 - **注意**:修改前需备份数据,并确保新长度能容纳所有现有值。 #### 为什么需要这个查询? - 在数据库设计中,`VARCHAR` 字段的长度直接影响存储效率和性能。MySQL 对 `VARCHAR` 的总长度限制为 65535 字节(包括所有列),超过会导致错误[^2]。 - 通过查询实际最大长度,可以避免过度分配空间,减少磁盘占用和I/O开销,从而优化查询速度[^3]。 #### 示例场景 假设 `products` 有字段 `description`(类型为 `VARCHAR(500)`),你想知道实际存储值的最大长度: ```sql SELECT MAX(LENGTH(description)) AS max_desc_length FROM products; ``` 如果返回值为 120,说明最大长度仅为120字节,建议优化为 `VARCHAR(130)` 以节省空间。 通过以上步骤,你可以高效地获取并利用varchar字段的长度信息,为数据库优化提供数据支持[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值