SqlServer 中行转列PIVOT函数用法

news/2025/3/20 20:49:07/文章来源:https://www.cnblogs.com/ZYPLJ/p/18783932

SqlServer 中行转列PIVOT函数用法

前言

最近在面试的时候,碰到了手写sql的题目,这让我这个面向AI的程序员着实难看。只见我面露难色,绞尽脑汁的情况下,终于还是放弃了。

这道题目不难,但是由于平时几乎没有遇到行转列的情况,导致在手写时忘记了PIVOT函数怎么使用😩。

面试准备不充分给自己找借口,菜就多练,不会写就别写。

题目描述

下面请看题:

假设有以下表 EmpCanlendar

Name CalendarDate ClassName
张三 2005-05-01 日班
张三 2005-05-02 日班
张三 2005-05-03 夜班
李四 2005-05-01 夜班
李四 2005-05-02 日班
... ... ...

输出结果:

Name D20050501 D20050502 D20050503 D20050504 D20050505
张三 日班 日班 日班 日班 夜班
李四 日班 日班 日班 NULL NULL
王五 NULL 夜班 夜班 NULL NULL

PIVOT函数简单介绍

PIVOT 是 SQL Server 中的一种功能,用于将行数据转换为列数据(即行转列)。它通常用于将某一列的唯一值作为新列,并将对应的值填充到这些新列中。PIVOT 是数据透视表的一种实现方式,非常适合用于统计和报表场景。

PIVOT 的基本语法

SELECT [非透视列],[透视值1], [透视值2], ..., [透视值N]
FROM (-- 子查询:提供原始数据SELECT [非透视列], [透视列], [值列]FROM 表名) AS 源表
PIVOT 
(聚合函数(值列) -- 例如 SUM、COUNT、MAX 等FOR 透视列 IN ([透视值1], [透视值2], ..., [透视值N])
) AS 透视表

参数

  1. 非透视列
    • 不需要转换的列,这些列的值将作为结果表的行标识。
  2. 透视列
    • 需要转换为新列的列。
  3. 值列
    • 需要填充到新列中的值。
  4. 聚合函数
    • 对值列进行聚合操作,例如 SUMCOUNTMAX 等。
    • 如果值列不需要聚合,可以使用 MAXMIN
  5. 透视值
    • 透视列中的唯一值,这些值将成为新列的名称。

解题

测试数据准备

CREATE TABLE #EmpCanlendar([Name] NVARCHAR(20) NULL,CalendarDate DATETIME NULL,ClassName NVARCHAR(10) NULL,
)
INSERT INTO #EmpCanlendar(Name,CalendarDate,ClassName)
VALUES
('张三','2005-05-01','日班'),
('张三','2005-05-02','日班'),
('张三','2005-05-03','日班'),
('张三','2005-05-04','日班'),
('张三','2005-05-05','夜班'),
('李四','2005-05-01','日班'),
('李四','2005-05-02','日班'),
('李四','2005-05-03','日班'),
('王五','2005-05-02','夜班'),
('王五','2005-05-03','夜班')

非动态sql

适用于日期范围固定,或者日期列较少的情况

SELECT Name,[2005-05-01] AS D20050501,[2005-05-02] AS D20050502,[2005-05-03] AS D20050503,[2005-05-04] AS D20050504,[2005-05-05] AS D20050505
FROM 
(SELECT Name, CalendarDate, ClassNameFROM #EmpCanlendar
) AS SourceTable
PIVOT
(MAX(ClassName)FOR CalendarDate IN ([2005-05-01], [2005-05-02], [2005-05-03], [2005-05-04], [2005-05-05])
) AS PivotTable;

查询结果

image

动态sql

适用于日期范围不固定,或者日期列较多的情况

SQL Server 2017及以上版本:

-- 声明变量存储动态 SQL
DECLARE @sql NVARCHAR(MAX) = ''
DECLARE @columns NVARCHAR(MAX) = ''SELECT @columns = STRING_AGG(QUOTENAME('D' + CONVERT(VARCHAR, DistinctDates.CalendarDate, 112)), ',')
FROM (SELECT DISTINCT CalendarDate FROM #EmpCanlendar) AS DistinctDatesSET @sql = 'SELECT Name , ' + @columns +'FROM(SELECT Name,''D'' + CONVERT(VARCHAR,CalendarDate, 112) CalendarDate,ClassNameFROM#EmpCanlendar) AS SourceTablePIVOT(MAX(ClassName)FOR CalendarDate IN ('+ @columns +')) AS PivotTable;
'
PRINT @sql
EXEC sp_executesql @sql

SQL Server 2017以下版本

SELECT @columns = STUFF((SELECT DISTINCT ',' + QUOTENAME('D'+ CONVERT(VARCHAR, CalendarDate, 112))FROM #EmpCanlendarFOR XML PATH('')),1, 1, ''
)

查询结果:

image

扩展

STUFF函数简单介绍

STUFF 是 SQL Server 中的一个字符串函数,用于删除字符串的一部分并在指定位置插入新的子字符串。它的主要作用是修改字符串的内容,通常用于拼接或替换字符串中的某些部分。

STUFF 函数的语法:

STUFF(原始字符串, 开始位置, 删除长度, 新子字符串)

参数

  1. 原始字符串
    • 需要修改的字符串。
    • 可以是字符型(CHARVARCHARNVARCHAR 等)的列、变量或表达式。
  2. 开始位置
    • 指定从原始字符串的哪个位置开始删除和插入。
    • 位置从 1 开始计数。
  3. 删除长度
    • 指定要删除的字符数。
    • 如果为 0,则不删除任何字符,仅插入新子字符串。
    • 如果大于原始字符串的长度,则从开始位置删除到字符串末尾。
  4. 新子字符串
    • 要插入的新字符串。
    • 如果为空字符串 '',则仅删除字符,不插入新内容。

可用于

  • 删除字符:从指定位置开始删除一定长度的字符。
  • 插入字符:在删除字符的位置插入新的子字符串。
  • 替换字符:通过删除和插入操作,可以实现字符串的替换。

STRING_AGG函数简单介绍:

STRING_AGG 是 SQL Server 2017 及更高版本中引入的一个聚合函数,用于将一组字符串值连接成一个单独的字符串,并使用指定的分隔符分隔每个值。它是 SQL Server 中处理字符串拼接的强大工具,特别适合将多行数据合并为一个字符串。

STRING_AGG 的基本语法

STRING_AGG(表达式, 分隔符)

参数

  1. 表达式
    • 需要拼接的字符串列或表达式。
    • 可以是 VARCHARNVARCHARCHAR 等字符类型。
  2. 分隔符
    • 用于分隔每个字符串值的字符或字符串。
    • 可以是任意字符串,例如 ,;- 等。

QUOTENAME函数简单介绍

在SQL Server中,QUOTENAME()函数用于将一个标识符(如表名、列名等)包围在方括号中,以防止引起语法错误或与关键字冲突。

QUOTENAME函数的语法:

QUOTENAME ( 'character_string' [ , 'quote_character' ] )

参数

'character_string':是要包围的标识符,可以是表名、列名等

'quote_character':是可选参数,用于指定用于包围标识符的字符,默认为方括号([ ])。

参考链接

  • 深入浅出:SQL Server 中的 PIVOTUNPIVOT 用法详解:https://blog.csdn.net/houbincarson/article/details/145483265
  • QUOTENAME (Transact-SQL) :https://learn.microsoft.com/zh-cn/sql/t-sql/functions/quotename-transact-sql?view=sql-server-ver16
  • SQL Serverquotename()函数怎么使用:https://www.cnblogs.com/luyj00436/p/18453443

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/902207.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第五周第四天

所用时间:180分钟 代码量(行):15 博客量(篇):1 了解到的知识点: 1.matplotlib的配置 因为要参加数学建模大赛,今天配置了python和matplotlib环境,尝试运行了程序,代码如下: import matplotlib.pyplot as plt import numpy as np# 生成数据 x = np.linspace(0, 10, …

Vue3中使用TinyMce编辑器

Vue3中使用TinyMce编辑器 - 知乎 一,安装TinyMce富文本vue npm install @tinymce/tinymce-vue -S npm install tinymce -STinyMce本身是英文编辑器,所以还需要下载中文本地化文件:https://www.tiny.cloud/get-tiny/language-packages/下载完成后放入node_modules下的tinymce…

入门Dify平台:如何根据需求选择与创建最合适的应用

今天我们将继续深入讲解Dify,重点介绍如何创建应用。具体来说,我们将探讨如何根据不同的需求来决定选择什么类型的应用最为合适,帮助大家更好地理解在Dify平台上构建应用的最佳实践。 创建空白应用 首先,我们需要进入Dify的首页选择工作室,并创建空白应用。如图所示:点击…

月暗推出音频模型 AudioX:任意内容生成音频和配乐;开源 TTS 模型 Orpheus,可生成叹息、笑声等非文本线索丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看点的 活动 」,但内容仅代表编辑…

202110211215 - IT项目管理笔记

IT项目管理中的百慕大 资源 、范围、进度 三角平衡 项目管理 -- 做事 启动、规划、执行、控制、收尾 项目管理 -- 四个层次: 复杂的事情简单化:分解 简单的事情量化:临界值 量化的事情专业化:规律 专业的事情模板化:框架模板 项目: 为创造特定产品或服务的一项有时限的任…

k8s拉取私有镜像的2种方式

k8s 在拉取私有镜像时 ,传递认证信息目录通过secret通过ServiceAccount 通过secret01-image-pull.yamlkind: Pod apiVersion: v1 metadata:name: imagepull-nginxlabels:group: imagepull spec:containers:- name: nginximage: registry.cn-beijing.aliyuncs.com/hkui_dev/ngi…

202110111235 - 软件工程笔记

1. 概述 1.1 开发只占冰山一角 1.2 计算机科学、数学,工程,管理 1.3 软件开发的本质:实现问题域中的概念和处理逻辑 到 运行平台的概念和处理逻辑的映射。系统建模 需求 -> 设计 -> 实现1.4 软件工程的目标:生产具有正确性、可用性、以及开销合宜的产品。 1.5 软件工…

202109060657 - hadoop架构和读写流程

1. 整体架构 hdfs架构zkmonode高可用。HA的工作原理?是否需要每个datanode监听zk?namenodeNameNode(nn):Hdfs集群的管理者,Master 管理Hdfs的名称空间(NameSpace) 维护副本策略 记录文件块(Block)的映射信息 负责处理客户端读写请求datanodeDataNode:NameNode下达命令,…

基于风险的完整性和检查建模(RBIIM)MATLAB仿真

1.程序功能描述 基于风险的完整性和检查建模(Risk-Based Integrity and Inspection Modeling ,RBIIM)MATLAB仿真,对比prior density,posterior perfect inspection,posterior imp inpection,cummulative posterior imperfect inspection四个指标。 2.测试软件版本以及…

202108151156 - kafka消费积压案例

0. 背景 上游厂家生产信令数据,我方消费kafka数据,过滤后插入HBase。 上游生产的信令数据分了4个主题,每个主题有若干分区,这4个主题的数据消费后都插入同一张HBase表。 问题:kafka消息积压达到百亿。 以下以topic1为例,有6个分区。 1. 查看消费滞后情况 kafka-consumer-…

mysql 多表怎么连接的

前言 简单描述一下多表怎么连接的。 正文 首先,我们得抛开我们一些自以为是的想法。 我想过这个问题,就是为什么我们背乘法口诀的时候,我们总是背: 22 = 4, 99=81 这样背下去,似乎这是口诀。然而这是缓存,不是计算,既然不是计算那么就不是逻辑学。 我们理所当然的想9*9…

202108120808 - 类加载器及双亲委派机制

Bootstrap ClassLoader 这是加载器中的大 Boss,任何类的加载行为,都要经它过问。它的作用是加载核心类库,也就是 rt.jar、resources.jar、charsets.jar 等。当然这些 jar 包的路径是可以指定的,-Xbootclasspath 参数可以完成指定操作。 这个加载器是 C++ 编写的,随着 JVM …