T-SQL Recipes之生成动态列表数据
Problem
首先什么是动态列表?举个示例,假设你想输出以逗号分隔的IDs,如:
1,45,67,199,298
Solution
生成动态列表数据在我们生活场景中很常见,比如在 Dynamic PIVOT中,解决方案也有许多种,小陈知道的大体有:
Cursor-Based
XML-Based
Set-Based
这三种方式,性能从低到高,有兴趣的看官可以自己看一下执行计划,分析数据。这里主要演示代码和思路为主。
Cursor-Based Approach
USE AdventureWorks2014;
GO DECLARE @nextid INT;
DECLARE @myIDs NVARCHAR(MAX) = '';
DECLARE idcursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT TOP 10
SalesOrderID
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC; OPEN idcursor;
FETCH NEXT FROM idcursor INTO @nextid;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @myIDs = @myIDs + CAST(@nextid AS NVARCHAR) + N',';
FETCH NEXT FROM idcursor INTO @nextid;
END --SET @myIDs = SUBSTRING(@myIDs, 1, LEN(@myIDs) -1)
SET @myIDs = STUFF(@myIDs,LEN(@myIDs), 1, '')
SELECT @myIDs AS comma_separated_output;
分析:Cursor-Based 的思路是迭代想要的结果集,一次一次加上,最后去掉最后一个逗号。关于去掉最后一个逗号,或者刚开始的,小陈推荐使用 STUFF() 函数.
PS: 小陈觉得应该在T-SQL私房菜中加一道常见有用函数的菜谱。
XML-Based Approach
USE AdventureWorks2014;
GO DECLARE @myIDs NVARCHAR(MAX) = ''; SET @myIDs = STUFF(
(SELECT TOP 10
N',' + CAST(SalesOrderID AS NVARCHAR) AS [text()]
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
FOR XML PATH('')), 1, 1, '');
/*
SET @myIDs = STUFF(
(SELECT TOP 10
',' + CAST(SalesOrderID AS NVARCHAR)
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
*/ SELECT @myIDs AS comma_separated_output;
分析:XML-Based 方式,初看之下觉得很复杂,不管怎么样,可读性上真的很差。对于看似复杂的T-SQL,小陈建议一步一步的分解,比如不了解XML AUTO PATH,可以移步MSDN查询一下。
PS:XML Reader不是免费的,在数据量大的情况下性能等同于迭代;这种方式易让别人觉得人你有奇技淫巧,一下下逼格就提高了。
Set-Based Approach
USE AdventureWorks2014;
GO DECLARE @myIDs NVARCHAR(MAX) = ''; SELECT TOP 10
@myIDs = @myIDs + N',' + CAST(SalesOrderID AS NVARCHAR)
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC SET @myIDs = STUFF(@myIDs, 1, 1, ''); SELECT @myIDs AS comma_separated_output;
分析:Set-Based 方式,不管是从性能上,还是从可读性上,都有很大的提升,也是小陈推荐的。
彩蛋
三种方式大体可以解决我们在T-SQL常见的问题,但有时候也会掉进坑里,有些也是动态列表不能解决的。
比如我们在写SP的时候,常把IDs作为参数传进去,然后在动态SQL中:orderid in @myIDs, 现实却是很骨感的……
T-SQL Recipes之生成动态列表数据的更多相关文章
- ajax获取动态列表数据后的分页问题
ajax获取动态列表数据后的分页问题 这是我在写前台网站时遇到的一个分页问题,由于数据是通过ajax的方式来请求得到的,如果引入相应的js文件来做分页,假如只是静态的填放数据到列表各项内容中(列表条数 ...
- 开源 免费 java CMS - FreeCMS1.9 移动APP生成网站列表数据
项目地址:http://www.freeteam.cn/ 生成网站列表数据 提取同意移动APP訪问的网站列表,生成json数据到/mobile/index.html页面. 从左側管理菜单点击生成网站列 ...
- 开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据
项目地址:http://www.freeteam.cn/ 生成栏目列表数据 提取当前管理网站下同意移动APP訪问的栏目列表,生成json数据到/site/网站文件夹/mobile/channels.h ...
- DB2存储过程实现查询表数据,生成动态SQL,并执行
一.动态执行SQL PREPARE S1 FROM 'delete from test'; EXECUTE S1; 二.使用游标 DECLARE V_CURSOR CURSOR FOR SELECT ...
- Excel 数据导入SQL XML 自动生成表头
去出差的时候应客户要求要要将Excel 文件内的数据批量导入到数据库中,而且有各种不同种类的表格,如果每一个表格多对应一个数据表的话, 按照正常的方法应该是创建数据表,创建数据库中映射的数据模型,然后 ...
- 【转】Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
原文链接:http://www.cnblogs.com/quanyongan/p/3152290.html 最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 ...
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 @DynamicUpdate 如果是在配置文件的话那就是dynamic -insert 和 dynamic- ...
- ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段
ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...
- 在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列)
原文:在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 1.如果去掉这个临时表中合计为0 ...
随机推荐
- java List 和Map的使用
一.MAP package net.xsoftlab.baike; import java.util.HashMap;import java.util.Iterator;import java.uti ...
- memcached的key,value,过期时间的限制
1. key值最大长度? memcached的key的最大长度是250个字符,是memcached服务端的限制. 如果您使用的客户端支持"key的前缀"或类似特性,那么key( ...
- Canvas绘制图形
1.Canvas绘制一个蓝色的矩形 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...
- jenkins使用简记
一.安装 jenkins有多种安装方式,可以使用内嵌的Servlet容器运行,也可以基于Apache运行,也可以安装成Linux或Windows服务. 1.使用 Servlet 容器运行 从官网下载 ...
- Unix目录结构的来历
作者: 阮一峰 Unix(包含Linux)的初学者,常常会很困惑,不明白目录结构的含义何在. 举例来说,根目录下面有一个子目录/bin,用于存放二进制程序.但是,/usr子目录下面还有/usr/bin ...
- 获取上个页面的url包括参数
Uri uri = Request.UrlReferrer; string path = uri.AbsoluteUri; TempData["path"] = path;
- EL算术表达式
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- [PHP][位转换积累]之与运算截取二进制流的值
function getBit( $num, $bit, $mask ){ return $num>>$bit&$mask; } var_dump( getBit( 41, 3, ...
- Sql Server 2008服务启动失败,错误17058
SQL Server (SQLEXPRESS) 服务因 17058 (0x42A2) 服务性错误而停止. 有关更多信息,请参阅在 http://go.microsoft.com/fwlink/even ...
- SQL优化
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...