热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

多行数据合并为单行的SQL技巧与案例

本文介绍了多种将多行数据合并为单行的方法,包括使用动态SQL、函数、CTE等技术,适用于不同的SQLServer版本。

-- 示例 1: 多行转单行及部分列转行
IF OBJECT_ID(N'[one]', N'U') IS NOT NULL DROP TABLE [one];
CREATE TABLE [one] (
[month] INT,
[day] INT,
[money] INT
);
INSERT INTO [one]
VALUES (10, 1, 200), (10, 2, 300), (10, 3, 400),
(11, 1, 500), (11, 2, 600), (11, 3, 700);

-- 使用动态SQL实现多行转单行
DECLARE @sql NVARCHAR(MAX) = N'SELECT [month]';
SELECT @sql += N', [' + CAST([day] AS NVARCHAR(10)) + N'] = SUM(CASE WHEN [day] = ' + CAST([day] AS NVARCHAR(10)) + N' THEN [money] ELSE 0 END)'
FROM (SELECT DISTINCT [day] FROM [one]) AS D;
SET @sql += N' FROM [one] GROUP BY [month];';
EXEC sp_executesql @sql;

-- 示例 2: 合并特定列的数据
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[two]') AND type IN (N'U'))
DROP TABLE [two];
CREATE TABLE [two] (
[id] INT IDENTITY(1, 1) NOT NULL,
[UserName] VARCHAR(50),
[Code] VARCHAR(50)
);

SET IDENTITY_INSERT [two] ON;
INSERT INTO [two] ([id], [UserName], [Code]) VALUES
(1, 'User1', 'A'), (1, 'User1', 'B'), (1, 'User2', 'C'),
(1, 'User2', 'D'), (1, 'User2', 'E'), (1, 'User3', 'F'),
(1, 'User3', 'G'), (1, 'User3', 'H'), (1, 'User3', 'I');
SET IDENTITY_INSERT [two] OFF;

-- 合并用户名对应的代码列表
SELECT B.UserName, LEFT(B.UserList, LEN(B.UserList) - 1) AS [List]
FROM (
SELECT [UserName],
(SELECT [Code] + ',' FROM [two] WHERE [UserName] = A.[UserName] ORDER BY [id] FOR XML PATH('')) AS UserList
FROM [two] A
GROUP BY [UserName]
) B;

-- 示例 3: 使用函数和CTE实现多行转单行
IF OBJECT_ID(N'[tb]', N'U') IS NOT NULL DROP TABLE [tb];
CREATE TABLE [tb] ([id] INT, [value] NVARCHAR(1));
INSERT INTO [tb] VALUES (1, N'a'), (1, N'b'), (1, N'c'), (2, N'd'), (2, N'e'), (3, N'f');

CREATE FUNCTION dbo.f_str(@id INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @result NVARCHAR(MAX) = '';
SELECT @result += ',' + [value]
FROM [tb]
WHERE [id] = @id;
RETURN STUFF(@result, 1, 1, '');
END;
GO

SELECT DISTINCT [id], [value] = dbo.f_str([id]) FROM [tb];

-- 使用CTE实现相同功能
WITH Roy AS (
SELECT [id], [value], [row] = ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [id])
FROM [tb]
), Roy2 AS (
SELECT [id], CAST([value] AS NVARCHAR(100)) AS [value], [row]
FROM Roy
WHERE [row] = 1
UNION ALL
SELECT a.[id], CAST(b.[value] + ',' + a.[value] AS NVARCHAR(100)), a.[row]
FROM Roy a
JOIN Roy2 b ON a.[id] = b.[id] AND a.[row] = b.[row] + 1
)
SELECT [id], [value]
FROM Roy2 a
WHERE [row] = (SELECT MAX([row]) FROM Roy WHERE [id] = a.[id])
ORDER BY [id]
OPTION (MAXRECURSION 0);

-- 示例 4: 合并特定类型的数据
IF OBJECT_ID(N'[tb]', N'U') IS NOT NULL DROP TABLE [tb];
CREATE TABLE [tb] (
[id] INT,
[type] VARCHAR(12)
);
INSERT INTO [tb]
VALUES (1, 'aa'), (2, 'bb'), (3, 'aa'), (4, 'aa'), (5, 'ab'), (6, 'bb'), (7, 'c'), (8, 'ac');

CREATE FUNCTION dbo.Fn_GetType_STR(@typeid VARCHAR(32))
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @s VARCHAR(1000) = '';
SELECT @s = ISNULL(@s + ',', '') + CAST([id] AS VARCHAR)
FROM [tb]
WHERE [type] = @typeid;
RETURN @s;
END;

SELECT DISTINCT [type], [str] = dbo.Fn_GetType_STR([type]) FROM [tb];

-- 示例 5: 最通用的多行转单行方法
DECLARE @tb TABLE (
[id] INT,
[value] VARCHAR(10)
);
INSERT INTO @tb
VALUES (1, 'aa'), (1, 'bb'), (2, 'aaa'), (2, 'bbb'), (2, 'ccc');

SELECT [id], [value] = STUFF((SELECT ',' + [value] FROM @tb t WHERE t.[id] = tv.[id] FOR XML PATH('')), 1, 1, '')
FROM @tb AS tv
GROUP BY [id];

-- 示例 6: 使用动态SQL实现多行转单行
IF OBJECT_ID(N'[tb]', N'U') IS NOT NULL DROP TABLE [tb];
CREATE TABLE [tb] ([col] VARCHAR(20));
INSERT INTO [tb] VALUES ('a'), ('b'), ('c'), ('d'), ('e');

-- 方法一
DECLARE @sql NVARCHAR(MAX) = '';
SELECT @sql += [col] + ','
FROM (SELECT [col] FROM [tb]) AS t;
SET @sql = 'SELECT [result] = ''' + LEFT(@sql, LEN(@sql) - 1) + '''';
EXEC sp_executesql @sql;

-- 方法二
DECLARE @output NVARCHAR(MAX) = '';
SELECT @output = COALESCE(@output + ',', '') + [col]
FROM [tb];
PRINT @output;

-- 方法三
SELECT (SELECT LTRIM([col]) + ',' FROM [tb] FOR XML PATH('')) AS [a];

-- 处理包含重复值的情况
IF OBJECT_ID(N'[a]', N'U') IS NOT NULL DROP TABLE [a];
CREATE TABLE [a] ([name] VARCHAR(50), [num] INT);
INSERT INTO [a] VALUES ('aa', 1), ('bb', 2), ('cc', 4), ('dd', 4), ('ee', 2);

DECLARE @STR NVARCHAR(MAX) = '';
SELECT @STR = ISNULL(@STR + ',', '') + [name]
FROM (SELECT DISTINCT [name] FROM [a]) AS T;
SELECT @STR;

 


推荐阅读
  • 本文将作为我硕士论文的一部分,但鉴于其内容的独特性和趣味性,决定单独发布。文中将定义一些皮亚诺公理,并介绍如何使用这些公理进行等式替换,以证明定理。 ... [详细]
  • 字符、字符串和文本的处理之Char类型
    .NetFramework中处理字符和字符串的主要有以下这么几个类:(1)、System.Char类一基础字符串处理类(2)、System.String类一处理不可变的字符串(一经 ... [详细]
  • 本文主要解决了在编译CM10.2时出现的关于Samsung Exynos 4 HDMI HAL库中SecHdmiV4L2Utils.cpp文件的编译错误。 ... [详细]
  • 转自:http:blog.sina.com.cnsblog_67419c420100vmkt.html 1.为什么要使用blocks将一个blocks作为函数或者方法的参数传递,可 ... [详细]
  • BeautifulSoup4 是一个功能强大的HTML和XML解析库,它能够帮助开发者轻松地从网页中提取信息。本文将介绍BeautifulSoup4的基本功能、安装方法、与其他解析工具的对比以及简单的使用示例。 ... [详细]
  • [编程题] LeetCode上的Dynamic Programming(动态规划)类型的题目
    继上次把backTracking的题目做了一下之后:backTracking,我把LeetCode的动态规划的题目又做了一下,还有几道比较难的Medium的题和Hard的题没做出来,后面会继续 ... [详细]
  • HDU1085 捕获本·拉登!
    问题描述众所周知,本·拉登是一位臭名昭著的恐怖分子,他已失踪多年。但最近有报道称,他藏匿在中国杭州!虽然他躲在杭州的一个洞穴中不敢外出,但近年来他因无聊而沉迷于数学问题,并声称如果有人能解出他的题目,他就自首。 ... [详细]
  • 本文详细介绍了如何将After Effects中的动画相机数据导入到Vizrt系统中,提供了一种有效的解决方案,适用于需要在广播级图形制作中使用AE动画的专业人士。 ... [详细]
  • 在使用Visual Studio构建项目时遇到了IntelliSense错误,具体表现为预期的')'未找到。本文提供了详细的解决方案和可能的原因分析。 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
  • A1166 峰会区域安排问题(25分)PAT甲级 C++满分解析【图论】
    峰会是指国家元首或政府首脑之间的会议。合理安排峰会的休息区是一项复杂的工作,理想的情况是邀请的每位领导人都是彼此的直接朋友。 ... [详细]
  • 本文详细介绍了Oracle RMAN中的增量备份机制,重点解析了差异增量和累积增量备份的概念及其在不同Oracle版本中的实现。通过对比两种备份方式的特点,帮助读者选择合适的备份策略。 ... [详细]
  • 构建Python自助式数据查询系统
    在现代数据密集型环境中,业务团队频繁需要从数据库中提取特定信息。为了提高效率并减少IT部门的工作负担,本文探讨了一种利用Python语言实现的自助数据查询工具的设计与实现。 ... [详细]
  • 本文介绍如何通过创建数据库触发器来限制Oracle数据库中特定用户的登录IP地址,以增强系统的安全性。示例代码展示了如何阻止非授权IP地址的登录尝试。 ... [详细]
  • Kubernetes Services详解
    本文深入探讨了Kubernetes中的服务(Services)概念,解释了如何通过Services实现Pods之间的稳定通信,以及如何管理没有选择器的服务。 ... [详细]
author-avatar
手机用户2502892403
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有