簡而言之,unpivot操作符就是取得乙個行的資料集合,然後把每一行都轉換成多個行資料。為了更好地理解,請看下圖:
圖1從上圖中,你能發現unpovot操作符,取得了兩行資料,每行包含三個price值,然後將這些轉化成6行資料,其中每個產品**都是乙個不同的行。
unpivot 命令制定了兩個不同的列型別。第乙個型別是列中不被轉換的。在例子中,id、產品名字列是這樣的列型別。第二種列型別就是那些被轉換的。諸如productcode, wholesale 和retail 這三列。在我上面的例子中,那些沒有被轉換的列將被在每套列值集合中重複,而另外的那些列將被轉換成行。
下面就是 unpivot 的語法:
select [columns not unpivoted],where:[unpivot_column],
[value_column],
from
()as unpivot ( [value_column] for [unpivot_column] in ( ) )
as
: 為源資料轉換後的表確定乙個別名。
: 被轉換的列的列名稱。
: 為轉換操作的整套生產,確定乙個別名。
為了更好地理解我們看下面的例子:
簡單的例子
use tempdb;listing 1: 建立並填充phonenumbers 資料goif object_id('phonenumbers') is not null drop table phonenumbers;
gocreate table phonenumbers (
personid int,
homephone varchar(12),
cellphone varchar(12),
workphone varchar(12),
faxnumber varchar(12));
insert into phonenumbers values
(1,null,'444-555-2931',null,null),
(2,'444-555-1950','444-555-2931',null, null),
(3,'444-555-1950', null,'444-555-1324','444-555-2310'),
(4,'444-555-1950','444-555-2931','444-555-1324',
'444-555-1987');
select personid, phonetype, phonenumberlisting 2: 行列轉換語法例子from (
select personid, homephone, cellphone, workphone, faxnumber
from phonenumbers ) as src
unpivot (
phonenumber for phonetype in
(homephone, cellphone, workphone, faxnumber)) as unpvt;
執行上面**後顯示如下圖:
通過這個例子,我們發現執行結果中每行資料只包含乙個單一的**號碼,同時注意到結果中在原表中有幾個號碼不為null則有幾行資料,id也就有幾次。接下來我們進一步通過使用unpivot來加深認識。
第二個例子中,我將使用兩個操作符來行轉列來轉換一套名字/值 的兩列資料。具體如下:
在表 custpref裡面 我有四對名稱和值。我們將使用不同的unpivot操作符來建立乙個結果集,每乙個preftype的名字和值針對每個custid 和custname。併聯使用操作符的作用是為了轉換兩組列。這樣講能表示為乙個引數名稱和值在一行裡面。執行**如下:
通過這個輸出結果,能發現不同的type對應不同的值得列,並且要關聯custid。整個查詢通過兩個不同的unpovot操作符同時使用了where 子句來合併輸出結果(基於列名前五個字元相同的進行匹配),第乙個行轉列轉換的是資料,第二個為型別,where限制了比較前五個字元,我能取得匹配的資料組。
**如下:
use tempdb;結果是與上面的例子完全相同的。godeclare @colnames varchar(1000);
set @colnames = '';
-- get prefvalue columns
select @colnames=stuff((
select distinct ',' + quotename(column_name)
from information_schema.columns p2
where table_name = 'custpref'
and column_name like 'pref_type'
for xml path(''), type).value('.', 'varchar(max)')
,1,1,'')
-- get preftype columns
declare @colvalues varchar(1000);
set @colvalues = '';
select @colvalues=stuff((
select distinct ',' + quotename(column_name)
from information_schema.columns p2
where table_name = 'custpref'
and column_name like 'pref_data'
for xml path(''), type).value('.', 'varchar(max)')
,1,1,'')
-- generate unpivot statement
declare @cmd nvarchar(2000);
set @cmd = 'select custid, custname, preftype, prefvalue from ' +
'(select custid, custname, ' + @colnames + ',' + @colvalues +
' from custpref) as perf unpivot (prefvalue for prefvalues in (' +
@colvalues + ')) as up1 unpivot (preftype for preftypes in (' +
@colnames + ')) as up2 where ' +
'substring(prefvalues,5,1) = substring(preftypes,5,1);'
-- print unpivot command
print @cmd
-- execute unpivot command
execute sp_executesql @cmd
為了完成和這個動態的sql,我使用了information_schema.columns檢視。這個檢視能幫我們設定兩個變數@colnames和
@colvalues ,這就包含了用逗號區分的列名的字串。這兩個變數被用來構建動態的行轉列查詢。一旦我建立了動態的sql就能,執行這個sp_executesql了。
這是乙個簡單的例項,但是相同的邏輯可以應用於更多的不同的組列的轉換。
unpivot操作符在2005 首次被引入,允許我們將多個name/value 列從不規範的表中建立到乙個規範畫的結果集中,並且一一對應於選定的列。通過使用這個操作符,我們能同時轉換多個不同組的name/value 的成對的列。
關於UNPIVOT 操作符
簡而言之,unpivot操作符就是取得乙個行的資料集合,然後把每一行都轉換成多個行資料。為了更好地理解,請看下圖 圖1從上圖中,你能發現unpovot操作符,取得了兩行資料,每行包含三個price值,然後將這些轉化成6行資料,其中每個產品 都是乙個不同的行。unpivot 命令制定了兩個不同的列型別...
關於CString的 操作符
檢查自已的 時,發現乙個比較弱智的錯誤,是關於轉碼的,和cstring的 操作符有關。為了能簡單重現,我模擬了一下 未有unicode或 unicode定義 uses conversion cstring stest t test中文 stest a2w stest messageboxw null...
關於操作符的總結
其中 的兩個運算元必須為整數。左移操作符 右移操作符 左移相當於乘法 左移1位,乘2 右移相當於除法 右移1位,除2 右移運算分為邏輯移位 左邊用0填充,右邊丟棄 和算術移位 左邊用符號位填充,右邊丟棄 按位與 按位或 按位異或 位操作符的運算元必須是整數。復合賦值符 sizeof,型別 其中 有按...