㈠ sql 行列轉換
前段時間有人問了一個問題,就是SQL的行列轉換,當時有點懵沒答上來,後來細細想一想,其實最近的一個項目就已經用到了。
基礎數據如下:
要求根據當年的月份去統計出每一個ID的匯總金額。就是把行中的月切換到列中。
最後效果如下:
參考資料: https://technet.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx#%E5%A4%8D%E6%9D%82%20PIVOT%20%E7%A4%BA%E4%BE%8B
帶批註的 PIVOT 語法。
如果聚合函數與 PIVOT 一起使用,則計算聚合時將不考慮出現在值列中的任何空值。
新建兩張表
查詢結果
--UNPIVOT 函數
--單純用SQL 處理 ,原理很簡單,就是對每個需要置換的列單獨處理出來
最終效果:
--用上面的結果新建表
--PIVOT
-- SQL直接處理,先用CASE 語句將每行處理出來,然後在用聚合去處理合並相同ID的行。
㈡ sql中一對多關系的查詢結果的多行轉換成一行多列
1、創建測試表,
create table test_fee(userid number, feeid number, fee number);
㈢ SQL行列轉換
SQL2000:
use Tempdb
go
--> -->
if not object_id(N'A') is null
drop table A
Go
Create table A([ID] nvarchar(5),[Name] nvarchar(4),[Age] int,[Sex] nvarchar(10))
Insert A
select N'a01',N'張三',19,N'男' union all
select N'a02',N'李四',20,N'女' union all
select N'a03',N'王五',21,N'男'
Go
if not object_id(N'B') is null
drop table B
Go
Create table B([表名] nvarchar(20),[列名] nvarchar(20),[欄位長度] int,[欄位組合] nvarchar(10))
Insert B
select N'A',N'ID',5,N'組合' union all
select N'A',N'Name',4,N'中文' union all
select N'A',N'Age',3,N'數字' union all
select N'A',N'Sex',2,N'選擇'
Go
--表名='A'(也就是A表), A表的ID='a01'
declare @TableName sysname,@ID nvarchar(10)
select @TableName='A',@ID='a01'
declare @S1 nvarchar(4000)
select @S1=isnull(@S1+' union all ','')+'select [列名]='+quotename(Name,'''')
+',[列欄位]= cast('+quotename(Name)+' as nvarchar(10)) from ['+@TableName+'] where ID='''+@ID+''''
from syscolumns where ID=object_id(@TableName)
exec(
'select b.[列名], a.[列欄位],b.[欄位長度], b.[欄位組合] from ('+@S1+N')a inner join B on a.[列名]=b.[列名] where b.[表名]='''+@TableName+'''')
/*
列名 列欄位 欄位長度 欄位組合
ID a01 5 組合
Name 張三 4 中文
Age 19 3 數字
Sex 男 2 選擇
*/
㈣ sql 行變成列
declare@snvarchar(4000)
select@s=isnull(@s+',','')+quotename(Name)
fromsyscolumnswhereID=object_id('aa')
orderbyColid
exec('selectid,namefromaaunpivot(nameforidin('+@s+'))b')
如圖:
㈤ sql 行轉列
SELECT DISTINCT
(SELECT a FROM tab WHERE b = '未知'),
(SELECT a FROM tab WHERE b = '輸入為空'),
(SELECT a FROM tab WHERE b = 'cc')
FROM tab
UNION ALL
SELECT
cast((SELECT a FROM tab WHERE b = '未知') / t.sumA AS DECIMAL(3, 1)),
(SELECT a FROM tab WHERE b = '輸入為空') / t.sumA,
(SELECT a FROM tab WHERE b = 'cc') / t.sumA
FROM (SELECT SUM(a) AS sumA FROM tab) t
這里cast((SELECT a FROM tab WHERE b = '未知') / t.sumA AS DECIMAL(3, 1)), 不同SQL方言轉化方式不一樣,目的是為了轉換成小數
㈥ SQL行轉列,列轉行
行列轉換在做報表分析時還是經常會遇到的,今天就說一下如何實現行列轉換吧。
行列轉換就是如下圖所示兩種展示形式的互相轉換
假如我們有下表:
通過上面 SQL 語句即可得到下面的結果
PIVOT 後跟一個聚合函數來拿到結果,FOR 後面跟的科目是我們要轉換的列,這樣的話科目中的語文、數學、英語就就被轉換為列。IN 後面跟的就是具體的科目值。
當然我們也可以用 CASE WHEN 得到同樣的結果,就是寫起來麻煩一點。
使用 CASE WHEN 可以得到和 PIVOT 同樣的結果,沒有 PIVOT 簡單直觀。
假設我們有下表 student1
通過 UNPIVOT 即可得到如下結果:
我們也可以使用下面方法得到同樣結果
㈦ SQL 行轉列
我這里兩種都給你介紹,行轉列和列轉行:
列轉行——
錄入經營范圍時候會遇到列傳行的問題解決方案如下:
在temp1 表有一下欄位內容:
㈧ SQL語句行轉列
根據樓主的描述,特為樓主總結如下,在SqlServer裡面行列轉換的語法一般是: select 欄位, sum(case when 要轉換的行單元格的欄位名='行欄位內容' then 聚合的欄位名 end ) as 自定義的列標題1 from 表的名字 group by 欄位(注意,分組聚合就是根據這個欄位來的,具體到樓主的問題,這里的欄位就應該是org_id) 如果有多個列,之間用逗號隔開就可以了,最後一個參數和from之間不要用逗號。 具體到樓主的顯示效果就可以這樣寫了。代碼參考如下: Select org_id , sum(case when channel ='團險' then PREM end) As '團險保費' , sum(case when channel ='個險' then PREM end) As '個險保費 From 你的表名 Group By org_id
㈨ sql行轉列
SELECT e.NAME as name,
count(case when DATEPART(year,c.START_TIME)=2014 then 1 else null end ) as count2014,
count(case when DATEPART(year,c.START_TIME)=2015 then 1 else null end ) as count2015
from ENVI_DATA_STATISTIC_COMP c
LEFT JOIN ENVI_CITY e on e.CITY_ID=c.CITY_ID
where c.COMP_NAME like '%藍天白雲%' and INDEX_TYPE='12'
and (c.START_TIME like '%2014-08%' or c.START_TIME like '%2015-08%' ) and STATISTIC_TYPE='1' and c.VALID_FLAG='1'
group by name
應該是醬紫的,使用case when 轉換~