group by的使用:https://blog.csdn.net/fz13768884254/article/details/82497404
经常写sql的都知道,group处理的sql,一般是为了获取一些统计参数,或者分组的字段等等,如果分组后,想要获取某个组内的所有字段,这时就需要使用GROUP_CONCAT(
expr
),详解如下:
此函数返回字符串结果,其中NULL
包含来自组的连接非值。NULL
如果没有非NULL
值,则返回 。完整语法如下:
GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]] [SEPARATOR str_val])
mysql> SELECT student_name, GROUP_CONCAT(test_score) FROM student GROUP BY student_name;
要么:
mysql> SELECT student_name, GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ') FROM student GROUP BY student_name;
在MySQL中,您可以获得表达式组合的连接值。要消除重复值,请使用该 DISTINCT
子句。要对结果中的值进行排序,请使用该ORDER BY
子句。要按相反顺序排序,请将DESC
(descending)关键字添加到要在ORDER BY
子句中排序的列的名称中。默认为升序; 这可以使用ASC
关键字明确指定。组中值之间的默认分隔符是逗号(,
)。要明确指定分隔符,请使用SEPARATOR
后跟应在组值之间插入的字符串文字值。要完全消除分隔符,请指定 SEPARATOR ''
。
结果被截断为group_concat_max_len
系统变量给出的最大长度,其默认值为1024.尽管返回值的有效最大长度受值的约束,但该值可以设置得更高max_allowed_packet
。group_concat_max_len
在运行时更改值的语法 如下,其中val
是无符号整数:
<span style="color:#555555"><span style="color:black"><code class="language-sql"><span style="color:#0077aa">SET</span> <span style="color:#999999">[</span><span style="color:#0077aa">GLOBAL</span> <span style="color:#a67f59">|</span> <span style="color:#0077aa">SESSION</span><span style="color:#999999">]</span> group_concat_max_len <span style="color:#a67f59">=</span> <em>val</em><span style="color:#999999">;</span></code></span></span>
返回值是非二进制或二进制字符串,具体取决于参数是非二进制还是二进制字符串。结果类型是TEXT
或者 BLOB
除非 group_concat_max_len
小于或等于512,在这种情况下结果类型是 VARCHAR
或 VARBINARY
。
项目应用:
项目中有一个需求,就是根据操作者获取管理帐号的数量,然后获取帐号下导入数据的数量。
第一步:根据操作者进行分组,获取所管理的帐号数量
第二步:根据帐号信息统计该这些帐号下所有导入数据量
第三步:汇总,完成
操作者 | 帐号数量 | 导入数据量 | 查询时间段 |
张山 | 3 | 28 | 2018-09-28 - 2018-09-29 |
李思 | 5 | 16 | 2018-09-28 - 2018-09-29 |
具体实现:
如果分组查询获取帐号数量,那么肯定要进行二次查询,获取当前操作者管理的所有帐号,再根据帐号获取导入数据量,这样需要连接两次数据库,操作也比较麻烦。
使用group_concat(account_id)就会一次查询出所有需要的信息,无需再次获取。
<resultMap id="AccountResultMap" type="com.test.entity.OperatorWorkStaDO" >
<result column="operator" property="operator" jdbcType="VARCHAR" />
<result column="num" property="num" jdbcType="BIGINT" />
<result column="ids" property="ids" jdbcType="VARCHAR" />
</resultMap>
<select id="getAccountIdByOperator" resultMap="AccountResultMap" >
select
operator,count(*) num ,GROUP_CONCAT(Aaccount_id) ids
from account_info
where create_time BETWEEN #{startTime} AND #{endTime}
<if test="operator != null">
and operator = #{operator}
</if>
GROUP BY operator ORDER by operator
</select>
这样获取到的ids就是一个字符串拼接的参数,例如"10021","10022","10028"
然后根据获取到的ids再统计导入数据量即可:
<select id="getDataNum" resultType="java.lang.Integer">
select
count(*)
from data_sta
where (create_time BETWEEN #{startTime} AND #{endTime}) and
<!--方案一,直接使用字符串-->
account_id in
(${ids})
<!--方案二,将字符串转为对应对象类型的集合
<foreach collection="ids" item="item" index="index" separator="," open="("
close=")">
#{item}
</foreach>-->
</select>
这样就可以统计数据啦,谢谢阅览。