㈠ sql 单列转多列多行!
以下 SQL 在 SQL Server 2008 Express 版本下,测试通过。
CREATE TABLE #temp (
name VARCHAR(10)
);
INSERT INTO #temp
SELECT '中国' UNION ALL
SELECT '美国' UNION ALL
SELECT '英国' UNION ALL
SELECT '德国' UNION ALL
SELECT '马来西亚' UNION ALL
SELECT '泰国' UNION ALL
SELECT '西班牙' UNION ALL
SELECT '越南' UNION ALL
SELECT '韩国' UNION ALL
SELECT '日本'
GO
SELECT
MAX( CASE WHEN Name_ID = 1 THEN name ELSE '' END ) AS 字段名称1,
MAX( CASE WHEN Name_ID = 2 THEN name ELSE '' END ) AS 字段名称2,
MAX( CASE WHEN Name_ID = 3 THEN name ELSE '' END ) AS 字段名称3,
MAX( CASE WHEN Name_ID = 0 THEN name ELSE '' END ) AS 字段名称4
FROM
(
SELECT
(ROW_NUMBER() OVER ( ORDER BY (SELECT 1) ) - 1) / 4 AS Line,
ROW_NUMBER() OVER ( ORDER BY (SELECT 1) ) % 4 AS Name_ID,
name
FROM
#temp
) SubQuery
GROUP BY
Line
GO
执行结果:
字段名称1 字段名称2 字段名称3 字段名称4
---------- ---------- ---------- ----------
中国 美国 英国 德国
马来西亚 泰国 西班牙 越南
韩国 日本
(3 行受影响)
㈡ sql 一行数据改成多行
您的方法(不建视图):
SELECT TOP 100 PERCENT *
FROM (SELECT *, SUBSTRING(Picture, 32, 30) AS PICTUREV FROM dbo.procts
WHERE (SUBSTRING(Picture, 32, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 63, 30) AS PICTUREV FROM dbo.procts
WHERE (SUBSTRING(PictureB, 63, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 94, 30) AS PICTUREV FROM dbo.procts
WHERE (SUBSTRING(PictureB, 94, 30) <> '')
) DERIVEDTBL
ORDER BY ...
我觉得您的子串应该是这样计算的,:
SUBSTRING(Picture, 0*31+1,30)
SUBSTRING(Picture, 1*31+1,30)
SUBSTRING(Picture, 2*31+1,30)
SUBSTRING(Picture, 3*31+1,30)
所以,在语句中这样写也会更好写,更容易理解,和更不容易出错。也不影响效率。
你的方法除了多余建了那么多视图,应该说是不错的方法了,但是实现不了不等长文件名按分隔符分离字串。
如果是分隔符为字串分段,您就必须要用我的自定义函数加我的语句。
如果是您写的那样,是固定长度的字串分段,那么就完全用你的方法,便是稍作改动,不用建中间视图
另外,您喜欢视图的话,可以建一个视图:
create view DERIVEDTBL
as
create view
SELECT *, SUBSTRING(Picture, 0*31+1,30) AS PICTUREV FROM dbo.procts WHERE (SUBSTRING(Picture, 32, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 1*31+1,30, 30) AS PICTUREV FROM dbo.procts WHERE (SUBSTRING(PictureB, 63, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 2*31+1,30, 30) AS PICTUREV FROM dbo.procts WHERE (SUBSTRING(PictureB, 94, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 3*31+1,30, 30) AS PICTUREV FROM dbo.procts WHERE (SUBSTRING(PictureB, 94, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 4*31+1,30, 30) AS PICTUREV FROM dbo.procts WHERE (SUBSTRING(PictureB, 94, 30) <> '')
union
SELECT *, SUBSTRING(Picture, 5*31+1,30, 30) AS PICTUREV FROM dbo.procts WHERE (SUBSTRING(PictureB, 94, 30) <> '')
--....向下任意延伸,只要改SUBSTRING中的序号就行了。
go
调用时这样就行了:
SELECT TOP N *
FROM DERIVEDTBL
ORDER BY ...
=================
一句解决问题,这样:
SELECT ID,TITLE,DBO.MYSPLIT(PICTURES,1,'|') AS PICTURE,1 AS SN from TABLENAME
UNION
SELECT ID,TITLE,DBO.MYSPLIT(PICTURES,2,'|') AS PICTURE,2 AS SN from TABLENAME
UNION
SELECT ID,TITLE,DBO.MYSPLIT(PICTURES,3,'|') AS PICTURE,3 AS SN from TABLENAME
UNION
SELECT ID,TITLE,DBO.MYSPLIT(PICTURES,4,'|') AS PICTURE,4 AS SN from TABLENAME
UNION
SELECT ID,TITLE,DBO.MYSPLIT(PICTURES,5,'|') AS PICTURE,5 AS SN from TABLENAME
UNION
SELECT ID,TITLE,DBO.MYSPLIT(PICTURES,6,'|') AS PICTURE,6 AS SN from TABLENAME
-- . . . . . .
ORDER BY ID,TITLE,SN
还有,您的这个函数求等长字串,不知道为什么没有首字串?
SUBSTRING(Picture, 32, 30)
就是这个个?
SUBSTRING(Picture, 1, 30)
===================
这里只给您写了6行,来满足您每ID最多6张图片的要求。写多少行都可以,即每ID最大图片数为6张。您可以写100行,1000行都行!
这里还给您多加了以个序号字段(SN),以保证图片顺序与原排列相同。如果不需要您可以去掉他。
下面的函数是一个非常有用的自定义数,是用来提取字串中某一部份的,请您执行一下,把他建立到您的数据库中,今后对您的编程会提供很大的方便。当然,本例所用的函数就是这个函数。
create FUNCTION mysplit--将以某分隔符分段的字串,按指定的顺序号提取子串
(@str nvarchar(2000),--源字串
@sn int, --提取序号
@Deli varchar(1) --分隔符
)
RETURNS varchar(100)
AS
BEGIN
declare @first int,@last int,@result varchar(1000),@sn0 int
select @sn0=0,@first=0,@LAST=1,@str=@str+REPLICATE(@DELI,1)
while @sn0!=@sn
begin
select @sn0=@sn0+1,@first=@LAST,@last=charindex(@DELI,@str,@LAST)+1
end
if @last-@first-1<0
set @result=''
else
SET @RESULT=SUBSTRING(@str,@FIRST,@LAST-@FIRST-1)
RETURN ( @RESULT )
END
GO
㈢ sql 怎么把一个字段的值分成多行
declare定义一个变量 @str 这个变量的属性为 varchar(100) 将'a.bb.ccc' 赋给变量 @str 下面的意思是从master(数据库的名字)中的spt_values(表名)查出字段为 col 的数据,同时这个是有条件的,where后面就是具体的条件:type=1同时 字段numb
㈣ MS SQL SERVER 如何把多列的值 , 变成一列多行 .
行转列,列转行是我们在开发过程中经常碰到的问题
行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现。用传统的方法,比较好理解。层次清晰,而且比较习惯。
但是PIVOT 、UNPIVOT提供的语法比一系列复杂的SELECT...CASE 语句中所指定的语法更简单、更具可读性.
--行转列的静态方案一:CASE WHEN,兼容sql2000
select custid,
3 sum(case when YEAR(orderdate)=2002 then qty end) as [2002],
sum(case when YEAR(orderdate)=2003 then qty end) as [2003],
sum(case when YEAR(orderdate)=2004 then qty end) as [2004]
from orders
group by custid;--行转列的静态方案二:PIVOT,sql2005及以后版本
select *
from (select custid,YEAR(orderdate) as years,qty from orders) as ord
pivot(sum(qty) for years in([2002],[2003],[2004]))as p
㈤ SQL数据库语句如何将一行变多行(sql多行数据转为一行多列)
用一个循环。
先用参数取到到底要变成多少行,和单价
declare@tint
declare@salnvarchar(8)
根据需运猛求或实际情况将应变为多少行这旁橡桥个烤取给变量@t,单价取给@sal
设置循环的起始数值
declare@iint
set@i=1
开始循环如御
while(@i<=@t)
begin
--将单行的数据插入需要的表
insertinto()
values()
--循环参数自增
set@i=@i1
end
㈥ 如何用SQL语句将数据一行变成多行呢
截断数据,在新增分隔符即可。
放大招
指定索引号,进行数据截取,返回处理后的字符串数组
string str =你的数据
str.substring(你想分的长度)你自己打印一个转换符就好了
㈦ sql 分列多行
参考以下sql
--测试一
--'abc|efg|hij|klm'参数一:截取的字符串str
--'|'参数二:在截取的字符串str中查询目标字符x
--1参数三:出现的位次n
--截取str中x出现n次之前的所有字符
--截取'abc|efg|hij|klm'中第一个'|'之前的所有字符abc
SELECTSUBSTRING_INDEX('abc|efg|hij|klm','|',1)
--测试二
--'abc|efg|hij|klm'参数一:截取的字符串str
--'|'参数二:在截取的字符串str中查询目标字符x
---1参数三:当为负数时,则表示倒序的位次
--截取str后中x出现从后往前数n次之后的所有字符
--截取'abc|efg|hij|klm'中从后往前数第一个'|'之后的所有字符klm
SELECTSUBSTRING_INDEX('abc|efg|hij|klm','|',-1)
㈧ mssql2008将一列值转换多行,不要用while循环,
CREATEFunctionSplit
(
@pvarchar(8000),
@dvarchar(10)
)
returns@tTable(tokenvarchar(100))
As
Begin
Declare@iInt
Set@p=RTrim(LTrim(@p))
Set@i=CharIndex(@d,@p)
While@i>=1
Begin
Insert@tValues(Left(@p,@i-1))
Set@p=SubString(@p,@i+1,Len(@p)-@i)
Set@i=CharIndex(@d,@p)
End
If@p<>''
Insert@tValues(@p)
Return
End
witht(id,name)as(select1,'a1:a2:a3:a4'
unionallselect2,'b1:b2:b3')
select*fromtcrossapplysplit(t.name,':')
㈨ sql2000 表中一列内容拆分转多行语句
--搭建环境
create table #(a int,b varchar(60))
insert into # select 1,'123,456,xxx,789' union all select 2,'321,213,sss,985'
select * from #
go
------------------------------测试---------------------------------------------
--update组成查询字符串
update # set b=';'+b+';'
update # set b=replace(b,';','''')
update # set b=replace(b,',',''',''')
go
--创建中间表
create table #tmp(a int identity(1,1),co1 varchar(10),co2 varchar(10),co3 varchar(10),co4 varchar(10))
go
--如果#表中行数太多,可能会超过8000的长度,可以考虑用游标替换这部分
declare @sql varchar(8000)
set @sql=''
select @sql=@sql+b+' union all select ' from #
select @sql='select '+left(@sql,len(@sql)-17)
select @sql='insert into #tmp(co1,co2,co3,co4) '+@sql
print @sql
exec(@sql)
select * from #tmp
---------------------------------
select a,co1 from #tmp union all
select a,co2 from #tmp union all
select a,co3 from #tmp union all
select a,co4 from #tmp
order by a