㈠ 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