当前位置:首页 > 问答 > 正文

数据库查询结果怎么拼接才方便又实用,select语句合并技巧分享

为什么需要拼接查询结果?

在日常工作中,我们经常会遇到这样的情况(来源:知乎多位数据分析师的经验分享):数据分散在不同的表里,或者即使在同一张表,一次查询无法直接得到我们最终想要的、规整的形态。

  • 报表需求:老板想要一份报告,里面既要看到每个员工的姓名、部门,又要看到他们当月的销售总额,而员工信息存在“员工表”,销售记录存在“订单表”。
  • 数据对比:想将今年第一季度的数据和去年同期的数据并排放在一起,方便进行对比分析。
  • 数据补全:从主表查询出一批商品ID和名称后,还需要从另一个详情表里取出这些商品对应的图片链接和详细描述。

这时候,简单的一条SELECT * FROM 某张表就不够用了,我们需要把多次查询的结果“拼接”起来,形成一个完整的数据视图,这里的“拼接”主要分为两大类:上下拼接左右拼接

左右拼接(横向合并):把表变“宽”

左右拼接就像是我们用Excel时,根据某个共同的列(比如学号),把两个表格的数据连接到一起,让信息更丰富,在SQL中,这主要通过JOIN(连接)关键字实现。

根据连接方式的不同,常见的有以下几种(来源:CSDN数据库教程类比生活场景的解释):

  1. 内连接(INNER JOIN):只取“交集”。

    • 像什么:好比是学校要组织一场“必须由班长和学习委员共同参加”的会议,你手里有班长名单(表A),也有学习委员名单(表B)。INNER JOIN的结果就是,找出那些既是班长又是学习委员的学生名单,如果某个学生只是班长但不是学委,或者只是学委但不是班长,他都不会出现在最终名单里。
    • 什么时候用:当你明确只需要两个表中都存在匹配记录的数据时,这是最常用的一种连接方式。
    • 简单例子SELECT A.员工姓名, A.部门, B.销售金额 FROM 员工表 A INNER JOIN 订单表 B ON A.员工ID = B.员工ID,这会得到每个员工及其对应的销售记录,没有销售记录的员工不会出现。
  2. 左连接(LEFT JOIN):以左边表为“主心骨”。

    • 像什么:还是上面的例子,现在学校组织一场“全体班长会议,并鼓励学习委员一同参加”,那么最终名单会包含所有班长,如果一个班长恰好也是学习委员,那么他的学委信息也会显示出来;如果一个班长不是学委,那么他的学委信息位置就是空的(NULL)。
    • 什么时候用:当你需要保留左表(FROM后面的表)的全部记录,即使它在右表里没有匹配项,这在查询“有还是没有”的问题时特别有用,查找所有员工,并显示他们的订单情况(包括没订单的员工)”。
    • 简单例子SELECT A.员工姓名, A.部门, B.销售金额 FROM 员工表 A LEFT JOIN 订单表 B ON A.员工ID = B.员工ID,这会列出所有员工,对于没有销售记录的员工,其“销售金额”字段会显示为NULL。
  3. 右连接(RIGHT JOIN):和左连接相反,以右边表为“主心骨”,但实践中,因为可以通过调整表的顺序用左连接替代,所以用得相对少一些。

使用JOIN的实用技巧:

  • 一定写好ON条件:这是JOIN的灵魂,告诉数据库根据哪个字段来匹配两张表,忘记写ON会导致产生巨量的错误数据(笛卡尔积)。
  • 使用表别名:尤其是当表名很长或者需要连接多张表时,用表名 AS 别名(如FROM employee AS e)可以大大简化SQL语句,让它更易读。
  • 明确指定字段:写SELECT时,尽量用表别名.字段名(如e.name, d.department_name)的方式,避免当不同表有相同列名时产生混淆错误。

上下拼接(纵向合并):把表变“长”

上下拼接就像是把两篇结构相同的文章首尾相接,变成一篇更长的文章,在SQL中,主要使用UNIONUNION ALL操作符。

  1. UNION ALL:最简单的合并,直接堆叠。

    • 像什么:把一月份的工资单和二月份的工资单简单地摞在一起,形成一份一月和二月总的工资清单,即使有完全相同的记录,也会保留两份。
    • 什么时候用:当你需要合并多个查询结果,并且不需要去除重复行时,因为UNION ALL不去重,它的效率比UNION更高。
    • 简单例子SELECT 产品名称, 价格 FROM 一季度产品表 UNION ALL SELECT 产品名称, 价格 FROM 二季度产品表,这会得到一个包含两个季度所有产品的列表。
  2. UNION:合并后自动去重。

    • 像什么:同样是合并工资单,但如果一个人在两个月的工资条完全一样(极罕见情况),UNION会自动只保留一条。
    • 什么时候用:当你确定合并的结果中可能存在完全重复的行,而你只需要唯一记录时,需要注意的是,去重操作会消耗更多的数据库资源,如果确定没有重复或不需要去重,应优先使用UNION ALL

使用UNION的注意事项:

  • 列数和类型必须匹配:要合并的每个SELECT语句,其选取的列数必须相同,且对应位置列的数据类型也必须是兼容的,比如第一个SELECT选了姓名(文本)和年龄(数字),第二个SELECT也得选一个文本列和一个数字列,顺序不能错。
  • 排序要在最后:如果需要对合并后的总结果排序,只需在最后一个SELECT语句后加上ORDER BY子句,而不能在每个SELECT语句后都加。

总结与选择

(来源:多位社区用户的经验之谈)

  • 增加列,让单条记录的信息更丰富?用JOIN(左右拼接),根据是否需要保留所有记录,选择INNER JOINLEFT JOIN
  • 增加行,把结构相同的数据集累加起来?用UNION ALLUNION(上下拼接),根据是否需要去除完全重复的行,选择效率更高的UNION ALL或带去重功能的UNION

实际业务中,这些技巧经常会组合使用,先通过JOIN从多张表获取到需要的宽表数据,然后再用UNION ALL将不同时间周期的数据合并起来,最终形成一个用于分析或报表的完整数据集,掌握好这两种基本的“拼接”思维,就能应对大部分复杂的数据查询场景了。

数据库查询结果怎么拼接才方便又实用,select语句合并技巧分享