1 背景

开发业务使用mysql数据库时,为了扩展性通常会使用列表(纵表)。如下图,在这个表中抽象出类型和值,当类型增加后,不需要改表结构,直接插入即可。

表名:config

type value
1 出行
1 饮食
1 娱乐
2 饮食
2 娱乐

有时候通过这类表建立配置表。初始会通过人工导入一些数据,同时要求数据必须满足某些条件,比如表中约定任意一个type都必须要有“出行”这个值。

在人工操作时,有时会发生忘记导入某些数据。从上面的例子看,就是2这个类型下缺少了出行这个值。因此需要通过SQL查询快速找到这种问题。

2 查询分组中是否包含某些值

为了解决背景中提到的问题,我们会利用group by及聚合函数来解决。还是使用背景中的例子,我们对数据按类型分组,随后查看分组中是否包含某个值。

select type,sum(value = '出行') from config 
group by type
  • 首先通过group by分组
  • 接着通过聚合函数sum[1]求出分组下value为出行的行数,sum函数入参可以是一个表达式,我们得出满足表达式的行的数量
  • 根据分析,求和后行数为0的为不满足条件的列。我们删选出后统一处理

由于条件中明确出行为必填值,那么在这个列表中我们还可以通过必填值,来找到不满足的type。我们限定好必填候选值,先看找出不包含这些候选值的列即可。 假设有多行候选数据,我们就要构造出多行数据。

  • 通过union all[2] 构造当列多行候选数据
select '出行' union all
select '饮食'
  • 查询包含候选数据的行,并去重类型type
select distinct type from config where value in
(
	select '出行' union all
	select '饮食'
)
  • 最后从所有type中取出满足条件的type得出结果

两种方式都涉及到表中列名获取,为了获取列表我们可以通过
INFORMATION_SCHEMA.COLUMNS[3]来获取列明

select * from INFORMATION_SCHEMA.COLUMNS

这种方式读取数据表的描述信息[4]来查询表结构定义。类型的还可以查询一个表的其它描述性信息。

3 总结

列表(纵表)快速检查是否包含某些数据,结合分组和聚合函数来处理。有时候也可以通过union来构造单列多行数据。为了进一步简化工作可以继读取数据表的元信息。

参考资料

[1].聚合函数sum,https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_sum
[2].mysql union,https://dev.mysql.com/doc/refman/8.0/en/union.html
[3].https://dev.mysql.com/doc/refman/8.0/en/information-schema-columns-table.html
[4]https://dev.mysql.com/doc/refman/8.0/en/information-schema.html

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐