当前位置: 首页 > java >正文

【数据库】使用Sql Server将分组后指定字段的行数据转为一个字段显示,并且以逗号隔开每个值,收藏不迷路

大家好,我是全栈小5,欢迎来到《小5讲堂》。
这是《Sql Server》系列文章,每篇文章将以博主理解的角度展开讲解。
温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!

在这里插入图片描述

目录

  • 前言
  • 示例
    • 数据集
    • 数据分组
    • 增加排序
  • 查询小技巧
    • 1. 使用 `WITH TIES` 获取并列结果(分页查询时特别有用)
    • 2. 使用 `OUTPUT` 子句捕获DML操作结果(避免二次查询)
    • 3. 使用 `CROSS APPLY` 优化复杂查询(替代JOIN的更好选择)
  • 文章推荐

前言

很久没有写报表了,今天尝试写下报表就遇到了一个常见但是太久了有点忘了的知识点。
那就是如何让指定字段的行数据转为一个字段显示并以逗号的形式隔开,一起来探讨下!

示例

STRING_AGG 是SQL Server 2017引入的新函数,更简洁高效

数据集

模拟表格数据,如下

select '张三' as NameText,'语文' as SubjectText
union all
select '张三' as NameText,'数学' as SubjectText
union all
select '张三' as NameText,'英语' as SubjectText
union all
select '张三' as NameText,'物理' as SubjectText
union all
select '张三' as NameText,'化学' as SubjectText
union all
select '张三' as NameText,'生物' as SubjectText
union all
select '张三' as NameText,'历史' as SubjectText
union all
select '张三' as NameText,'政治' as SubjectText
union all
select '张三' as NameText,'地理' as SubjectText
union all
select '张三' as NameText,'体育' as SubjectText
union all
select '张三' as NameText,'音乐' as SubjectText
union all
select '张三' as NameText,'美术' as SubjectText
union all
select '李四' as NameText,'体育' as SubjectText
union all
select '李四' as NameText,'音乐' as SubjectText
union all
select '李四' as NameText,'美术' as SubjectText

在这里插入图片描述

数据分组

以姓名为分组,增加多一个科目字段,并且科目名称以逗号形式隔开,效果如下:
在这里插入图片描述

string_agg(cast(字段 as varchar), ‘,’) as 自定义名称

select t.NameText
,string_agg(cast(t.SubjectText as varchar), ',') as ALLSubject
from(select '张三' as NameText,'语文' as SubjectTextunion allselect '张三' as NameText,'数学' as SubjectTextunion allselect '张三' as NameText,'英语' as SubjectTextunion allselect '张三' as NameText,'物理' as SubjectTextunion allselect '张三' as NameText,'化学' as SubjectTextunion allselect '张三' as NameText,'生物' as SubjectTextunion allselect '张三' as NameText,'历史' as SubjectTextunion allselect '张三' as NameText,'政治' as SubjectTextunion allselect '张三' as NameText,'地理' as SubjectTextunion allselect '张三' as NameText,'体育' as SubjectTextunion allselect '张三' as NameText,'音乐' as SubjectTextunion allselect '张三' as NameText,'美术' as SubjectTextunion allselect '李四' as NameText,'体育' as SubjectTextunion allselect '李四' as NameText,'音乐' as SubjectTextunion allselect '李四' as NameText,'美术' as SubjectText
) t
group by t.NameText

增加排序

通过输出结果可能会注意到,以逗号隔开的文本不是按顺序,和表格本身排序不一致。
假设根据id进行升序排序输出,确保一致,如下:
在这里插入图片描述

string_agg(cast(字段 as varchar), ‘,’) within group (order by 排序字段 asc) as 自定义名称

select t.NameText
,string_agg(cast(t.SubjectText as varchar), ',') within group (order by t.id asc) as ALLSubject
from(select 1 as id,'张三' as NameText,'语文' as SubjectTextunion allselect 2 as id,'张三' as NameText,'数学' as SubjectTextunion allselect 3 as id,'张三' as NameText,'英语' as SubjectTextunion allselect 4 as id,'张三' as NameText,'物理' as SubjectTextunion allselect 5 as id,'张三' as NameText,'化学' as SubjectTextunion allselect 6 as id,'张三' as NameText,'生物' as SubjectTextunion allselect 7 as id,'张三' as NameText,'历史' as SubjectTextunion allselect 8 as id,'张三' as NameText,'政治' as SubjectTextunion allselect 9 as id,'张三' as NameText,'地理' as SubjectTextunion allselect 10 as id,'张三' as NameText,'体育' as SubjectTextunion allselect 11 as id,'张三' as NameText,'音乐' as SubjectTextunion allselect 12 as id,'张三' as NameText,'美术' as SubjectTextunion allselect 13 as id,'李四' as NameText,'体育' as SubjectTextunion allselect 14 as id,'李四' as NameText,'音乐' as SubjectTextunion allselect 15 as id,'李四' as NameText,'美术' as SubjectText
) t
group by t.NameText

查询小技巧

以下是三个能提高你SQL Server查询效率和便利性的实用技巧:

1. 使用 WITH TIES 获取并列结果(分页查询时特别有用)

-- 获取前10条记录,包括与第10条记录值相同的所有记录
SELECT TOP 10 WITH TIES column1, column2
FROM table_name
ORDER BY column1 DESC;

应用场景:当你想获取排名靠前的记录,但不想因为TOP N的限制而遗漏与第N条记录值相同的其他记录。

2. 使用 OUTPUT 子句捕获DML操作结果(避免二次查询)

-- 更新数据同时返回被更新的记录
UPDATE table_name
SET column1 = 'new_value'
OUTPUT inserted.*  -- 返回更新后的数据
WHERE condition;-- 删除数据同时返回被删除的记录
DELETE FROM table_name
OUTPUT deleted.*  -- 返回被删除的数据
WHERE condition;

优势:减少数据库往返次数,提高效率,特别适合需要记录变更的场景。

3. 使用 CROSS APPLY 优化复杂查询(替代JOIN的更好选择)

-- 获取每个客户的最新订单
SELECT c.CustomerID, c.CustomerName, o.OrderDate, o.Amount
FROM Customers c
CROSS APPLY (SELECT TOP 1 OrderDate, AmountFROM OrdersWHERE CustomerID = c.CustomerIDORDER BY OrderDate DESC
) o;

优势

  • 比子查询更高效
  • 比LEFT JOIN + GROUP BY更简洁
  • 特别适合需要为每行主表获取一个相关子表记录的场景

这些技巧能帮助你写出更高效、更简洁的SQL查询语句,提高数据库操作效率。

文章推荐

【数据库】使用Sql Server将分组后指定字段的行数据转为一个字段显示,并且以逗号隔开每个值,收藏不迷路

【数据库】SQL Server 查询条件小技巧:ISNULL 函数的使用,有请DeepSeek来辅助讲解下

【Sql Server】在SQL Server中生成雪花ID(Snowflake ID)

【Sql Server】使用row_number over方式进行表分页,数据量达到五千多条记录后,查询变慢需要20多秒的解决方案

【Sql Server】随机查询一条表记录,并重重温回顾下自定义函数的封装和使用

【Sql Server】锁表如何解锁,模拟会话事务方式锁定一个表然后进行解锁

【Sql Server】通过Sql语句批量处理数据,使用变量且遍历数据进行逻辑处理

【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据

【新星计划回顾】第四篇学习计划-自定义函数、存储过程、随机值知识点

【Sql Server】Update中的From语句,以及常见更新操作方式

【Sql server】假设有三个字段a,b,c 以a和b分组,如何查询a和b唯一,但是c不同的记录

【Sql Server】新手一分钟看懂在已有表基础上修改字段默认值和数据类型

总结:温故而知新,不同阶段重温知识点,会有不一样的认识和理解,博主将巩固一遍知识点,并以实践方式和大家分享,若能有所帮助和收获,这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。

http://www.xdnf.cn/news/16516.html

相关文章:

  • uniapp,uview 报错:Not Found:Page[2][-1;-1,8,0,28] at view.umd.min.js:1
  • 从fork到exit:剖析Linux进程的诞生、消亡机制
  • 阿里云通义灵码深度解析:AI编程时代的技术革命与实践探索
  • 计算机毕设分享-基于SpringBoot的健身房管理系统(开题报告+前后端源码+Lun文+开发文档+数据库设计文档)
  • Windows---动态链接库Dynamic Link Library(.dll)
  • Java AI面试实战:Spring AI与RAG技术落地
  • Rust赋能智能土木工程革新
  • 【LeetCode 热题 100】51. N 皇后——回溯
  • Java面试全方位解析:从基础到AI的技术交锋
  • 【Python系列】使用 memory_profiler 诊断 Flask 应用内存问题
  • 单表查询-or优化
  • K-近邻算法
  • Linux之shell脚本篇(三)
  • 3D碰撞检测系统 基于SAT算法+Burst优化(Unity)
  • rust- 定义模块以控制作用域和隐私
  • 任务提醒工具怎么选?对比16款热门软件
  • 2025年Agent创业实战指南:从0到1打造高增长AI智能体项目
  • 撤销连续三年不使用注册商标一次下受理书!
  • Spring之【Bean的生命周期】
  • Android MQTT 长连接最佳实践技术分享
  • Amazon Relational Database Service (Amazon RDS)入门课
  • C++ 构造函数中阻止资源泄漏的实践探索
  • Linux驱动20 --- FFMPEG视频API
  • 【 Python 】Collections库权威指南
  • 【多模态】天池AFAC赛道四-智能体赋能的金融多模态报告自动化生成part1-数据获取
  • 卫星图像数据集在农业领域的应用
  • Leetcode力扣解题记录--第136题(查找单数)
  • Redis C++客户端——命令使用
  • Vue 框架 学习笔记
  • 9-大语言模型—Transformer 核心:多头注意力的 10 步拆解与可视化理解