1. 程式人生 > >SQL Server 行轉列,列轉行。多行轉成一列

SQL Server 行轉列,列轉行。多行轉成一列

一、多行轉成一列(並以","隔開)

表名:A

表資料:

想要的查詢結果:

查詢語句:

SELECT  name ,
        value = ( STUFF(( SELECT    ',' + value
                          FROM      A
                          WHERE     name = Test.name
                        FOR
                          XML PATH('')
                        ), 1, 1, '') )
FROM    A AS Test
GROUP BY name;

PS:STUFF語句就是為了去掉第一個【逗號】

附STUFF用法:(從原字元的第二個開始共三個字元替換為後面的字元)

SELECT STUFF('abcdef', 2, 3, 'ijklmn'); 

查詢結果:aijklmnef

二、一列轉成多行

表名:tb

表資料:

想要的結果:

查詢語句:

SELECT a.[name],b.[value]
FROM (SELECT [name],[value]=CAST('<v>'+REPLACE([value],',','</v><v>')+'</v>' AS xml) FROM tb) a
OUTER APPLY (SELECT
[value]=T.C.value('.','varchar(50)') FROM a.[value].nodes('/v') AS T(C)) b

三、行轉列(轉自大神張志濤的部落格 http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html)

1、建立表格

IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb

go

CREATE TABLE tb(姓名 VARCHAR(10),課程 VARCHAR(10),分數 INT)

INSERT INTO tb VALUES('張三','語文',74)

INSERT INTO
tb VALUES('張三','數學',83) INSERT INTO tb VALUES('張三','物理',93) INSERT INTO tb VALUES('李四','語文',74) INSERT INTO tb VALUES('李四','數學',84) INSERT INTO tb VALUES('李四','物理',94) go SELECT * FROM tb

2、使用SQL Server 2000靜態SQL

SELECT 姓名,

 max(CASE 課程 WHEN '語文' THEN 分數 ELSE 0 end)語文,

 max(CASE 課程 WHEN '數學' THEN 分數 ELSE 0 end)數學,

 max(CASE 課程 WHEN '物理' THEN 分數 ELSE 0 end)物理

FROM tb

GROUP BY 姓名

3、使用SQL Server 2005靜態SQL

SELECT  *
FROM    tb PIVOT( MAX(分數) FOR 課程 IN ( 語文, 數學, 物理 ) ) a;

4、使用SQL Server 2005動態SQL

--使用stuff()

DECLARE @sql VARCHAR(8000)

SET @sql=''  --初始化變數@sql

SELECT @sql=@sql+','+課程 FROM tb GROUP BY 課程 --變數多值賦值

SET @sql=stuff(@sql,1,1,'')--去掉首個','

SET @sql='select * from tb pivot (max(分數) for 課程 in ('+@sql+'))a'

exec(@sql)

 

--或使用isnull()

DECLARE @sql VARCHAR(8000)


SELECT @sql=isnull(@sql+',','')+課程 FROM tb GROUP BY 課程           

SET @sql='select * from tb pivot (max(分數) for 課程 in ('+@sql+'))a'

exec(@sql)

四、行轉列結果加上總分、平均分

1、使用SQL Server 2000靜態SQL

SELECT 姓名,

max(CASE 課程 WHEN '語文' THEN 分數 ELSE 0 end)語文,

max(CASE 課程 WHEN '數學' THEN 分數 ELSE 0 end)數學,

max(CASE 課程 WHEN '物理' THEN 分數 ELSE 0 end)物理,

sum(分數)總分,

cast(avg(分數*1.0)AS DECIMAL(18,2))平均分

FROM tb

GROUP BY 姓名

2、使用SQL Server 2000動態SQL

DECLARE @sql VARCHAR(500)

SET @sql='select 姓名'

SELECT @sql=@sql+',max(case 課程 when '''+課程+''' then 分數 else 0 end)['+課程+']'

from(SELECT DISTINCT 課程 FROM tb)a

SET @sql=@sql+',sum(分數) 總分,cast(avg(分數*1.0) as decimal(18,2)) 平均分 from tb group by 姓名'

exec(@sql)

3、使用SQL Server 2005靜態SQL

SELECT m.*,n.總分,n.平均分

from

(SELECT * FROM tb pivot(max(分數)FOR 課程 IN(語文,數學,物理))a)m,

(SELECT 姓名,sum(分數) 總分,cast(avg(分數*1.0)AS DECIMAL(18,2))平均分

FROM tb

GROUP BY 姓名)n

WHERE m.姓名=n.姓名

4、使用SQL Server 2005動態SQL

--使用stuff()

--

DECLARE @sql VARCHAR(8000)

SET @sql=''  --初始化變數@sql

SELECT @sql=@sql+','+課程 FROM tb GROUP BY 課程 --變數多值賦值

--同select @sql = @sql + ','+課程from (select distinct課程from tb)a

SET @sql=stuff(@sql,1,1,'')--去掉首個','

SET @sql='select m.* , n.總分,n.平均分 from

(select * from (select * from tb) a pivot (max(分數) for 課程 in ('+@sql+')) b) m ,

(select 姓名,sum(分數) 總分, cast(avg(分數*1.0) as decimal(18,2))平均分 from tb group by 姓名) n

where m.姓名= n.姓名'

exec(@sql)

 

--或使用isnull()

DECLARE @sql VARCHAR(8000)

SELECT @sql=isnull(@sql+',','')+課程 FROM tb GROUP BY 課程

SET @sql='select m.* , n.總分, n.平均分 from

(select * from (select * from tb) a pivot (max(分數) for 課程 in ('+@sql+')) b) m ,

(select 姓名,sum(分數)總分, cast(avg(分數*1.0) as decimal(18,2))平均分 from tb group by 姓名) n

where m.姓名= n.姓名'

exec(@sql)

五、列轉行

1、建立表格

IF OBJECT_ID('tb')IS NOT NULL DROP TABLE tb

go

CREATE TABLE tb(姓名 VARCHAR(10),語文 INT,數學 INT,物理 INT)

INSERT INTO tb VALUES('張三',74,83,93)

INSERT INTO tb VALUES('李四',74,84,94)

go

SELECT * FROM tb

go

2、使用SQL Server 2000靜態SQL

--SQL SERVER 2000靜態SQL。

SELECT * FROM

(

 SELECT 姓名,課程='語文',分數=語文 FROM tb

 UNION ALL

 SELECT 姓名,課程='數學',分數=數學 FROM tb

 UNION ALL

 SELECT 姓名,課程='物理',分數=物理 FROM tb

) t

ORDER BY 姓名,CASE 課程 WHEN '語文' THEN 1 WHEN '數學' THEN 2 WHEN '物理' THEN 3 end

2、使用SQL Server 2000動態SQL

--SQL SERVER 2000動態SQL。

--呼叫系統表動態生態。

DECLARE @sql VARCHAR(8000)

SELECT @sql=isnull(@sql+' union all ','')+' select 姓名, [課程]='

+quotename(Name,'''')+' , [分數] = '+quotename(Name)+' from tb'

FROM syscolumns

WHERE Name!='姓名' AND ID=object_id('tb')--表名tb,不包含列名為姓名的其他列

ORDER BY colid

exec(@sql+' order by 姓名')

go

3、使用SQL Server 2005靜態SQL

--SQL SERVER 2005動態SQL

SELECT 姓名,課程,分數 FROM tb unpivot (分數 FOR 課程 IN([語文],[數學],[物理])) t

4、使用SQL Server 2005動態SQL

--SQL SERVER 2005動態SQL

DECLARE @sql NVARCHAR(4000)

SELECT @sql=isnull(@sql+',','')+quotename(Name)

FROM syscolumns

WHERE ID=object_id('tb')AND Name NOT IN('姓名')

ORDER BY Colid

SET @sql='select 姓名,[課程],[分數] from tb unpivot ([分數] for [課程] in('+@sql+'))b'

exec(@sql)
轉自:http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html

相關推薦

SQL Server 轉行

一、多行轉成一列(並以","隔開)表名:A表資料:想要的查詢結果:查詢語句:SELECT name , value = ( STUFF(( SELECT ',' + value FROM A

SQL Server 執行計劃利用統計信息對數據的預估原理二(為什麽復合索引順序會影響到執行計劃對數據的預估)

pan new statistic 細心 參考 gin 技術分享 重建 target 本文出處:http://www.cnblogs.com/wy123/p/6008477.html   關於統計信息對數據行數做預估,之前寫過對非相關列(單獨或者單獨的索

SQL

CREATE TABLE [dbo].[a]([id] [nchar] (10) COLLATE Chinese_PRC_CI_AS NULL,[name] [nchar] (10) COLLATE Chinese_PRC_CI_AS NULL,[value] [nchar]

oracle (轉行)、

1.多列轉成一列(列轉行) --6列轉成兩列(列轉行) 這就是最常見的列轉行,主要原理是利用SQL裡面的union with temp as  (select    a.iid_sn,    a.product_name,    a.sales_figures,    a

SQL SERVER簡單的增改 語句 表關聯查詢 (去掉關鍵查詢)

insert into tb_UserInfo values('趙六',3,13512458679); --增加語句-- update tb_UserInfo set name='劉德華'where id=3; --修改語句-- delete from tb

oracle資料庫把某資料資料

select running_time, running_user, algorithm_id, algorithm_list_id, name1, name2, ROWNUM, wm_concat(t

如何在MySQL裡構造SQL語句自動給查詢出來的結果加從1開始的序號

兩種辦法: 第一種:快捷 select (@i:[email protected]+1) as i,a.* from zakk_carinfo_201811 a,(select @i:=0) as it where CI_ThroughTime between "2018-11-2

SQL SERVER Date和Time合併處理報表資料

問題原由: intouch專案中,利用intouch指令碼來儲存資料時,存入的時間格式為:date,time分開儲存。在報表需求中,有需要利用查詢兩個時間段之間的資料。 問題解決: 1.直接寫指令

sql server 和 oracle 中ip與數字互

(一)Oracle中: (1) IP轉為數字: createorreplacefunction ip2number(ip varchar2)    return number   is  

hive函式--union all &一行拆lateral view explode&一行group_concat()

工作幾年,越來越發現行列轉換非常重要,為了和上篇文章(hive函式--排序row_number,rank over)保持一致,這次繼續用學生成績的例子吧。1.行轉列 union all:表result:student_id,class,score學生的語數外物化都在一張表裡,

Bash終端命令使用privoxy將socks代理http代理

安裝privoxy # Ubuntu/debian sudo apt-get install privoxy # Centos sudo yum install privoxy # Mac osx sudo port install privoxy

SQL Server 並行操作優化避免並行操作被抑制而影響SQL的執行效率

情況 無法 ima rom 謝謝 tro 開啟 導致 edate 為什麽我也要說SQL Server的並行: 這幾天園子裏寫關於SQL Server並行的文章很多,不管怎麽樣,都讓人對並行操作有了更深刻的認識。 我想說的是:盡管並行操作可能(並不是一定)存

SQL Server數據庫mdf文件中了勒索病毒[@qq.com].java擴展名變為java

ffffff term blog 病毒 mark 分享圖片 ges png 勒索 SQL Server數據庫mdf文件中了勒索病毒[[email protected]].java。擴展名變為.java *****.mdf.id-923C7C92.[decrypthelp

SQL Server日誌過大清理日誌

  直接執行下面的程式碼 USE [master] GO ALTER DATABASE 資料庫 SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE 資料庫 SET RECOVERY SIMPLE

SQL之merge into 批量更新資料 Merge關鍵字是一個神奇的DML關鍵字它在SQL Server 2008被引入它能將Insert,Update,Delete簡單的併為M

轉載http://www.cnblogs.com/ruiati/archive/2013/01/18/2866017.html     Merge關鍵字是一個神奇的DML關鍵字。它在SQL Server 2008被引入,它能將Insert,Up

SQL Server 2008R2各個版本如何檢視是否啟用剩餘可用日期?

SELECT create_date AS 'SQL Server Installed Date', Expiry_date AS 'SQL Server Expiry Date', DATEDIFF(dd,create_date, GETDATE()) 'No_of_Days_Used'

SQL Server安裝完成後沒有顯示連線資料庫的客戶端圖示這是怎麼回事?少一個元件!!!

SQL Server安裝完成後,沒有顯示連線資料庫的客戶端圖示,這是怎麼回事?少一個元件!!! 1、話不多說,下載這個元件,路徑安裝選擇和剛開始沒完全安裝SQL Server的路徑保持一致,即可 2、缺少一個Microsoft SQL Server Management Stu

SQL Server創建Job 實現執行相同腳本而產生不同作業計劃的探究

完整 配置 not select active dst flags 分享圖片 fail 1 . 背景描述 本公司的SQL Server 服務器近百臺,為了收集服務器運行的狀態,需要在各個實例上部署監控Job,將收集到的信息推送到中央管理服務器。 收集的信息主要包括:慢查詢、

SQL Server中的日期時間組合查詢

如圖所示,Jdate和Jdate2是兩個分開的欄位,一個是date型別,儲存日期,一個是time(0)型別,儲存具體時間 現在有這樣的要求,就是獲得(Jdate和Jdate2組合起來的日期時間)在(當前日期時間之後)的資料 一開始我是用的SQL語句是  select * from tab

sql server啟動不了 MSSQL 18052錯誤: 9003嚴重度: 20狀態: 1

問題現象: 系統日誌檔案(控制面板–管理工具–系統日誌) 能找到以下兩條錯誤: 17052: 無法恢復 master 資料庫。正在退出。 18052: 錯誤: 9003,嚴重度: 20,狀態: 1。 解決方法: 將Microsoft SQL Server/MSSQL/Data 目錄改名