主頁 > 知識(shí)庫 > 一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換語句

一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換語句

熱門標(biāo)簽:知名電銷機(jī)器人價(jià)格 外呼系統(tǒng)改進(jìn) 長沙智能外呼系統(tǒng) 地圖標(biāo)注牌 湖南電腦外呼系統(tǒng)平臺(tái) 廣東防封卡外呼系統(tǒng)原理是什么 分享百度地圖標(biāo)注多個(gè)位置 電銷機(jī)器人公司 需要哪些牌照 菏澤語音電銷機(jī)器人加盟公司
一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換
Author: eaglet
在數(shù)據(jù)庫開發(fā)中經(jīng)常會(huì)遇到行列轉(zhuǎn)換的問題,比如下面的問題,部門,員工和員工類型三張表,我們要統(tǒng)計(jì)類似這樣的列表
部門編號(hào) 部門名稱 合計(jì) 正式員工 臨時(shí)員工 辭退員工
1 A 30 20 10 1
這種問題咋一看摸不著頭緒,不過把思路理順后再看,本質(zhì)就是一個(gè)行列轉(zhuǎn)換的問題。下面我結(jié)合這個(gè)簡(jiǎn)單的例子來實(shí)現(xiàn)行列轉(zhuǎn)換。
下面3張表
復(fù)制代碼 代碼如下:

if exists ( select * from sysobjects where id = object_id ( ' EmployeeType ' ) and type = ' u ' )
drop table EmployeeType
GO
if exists ( select * from sysobjects where id = object_id ( ' Employee ' ) and type = ' u ' )
drop table Employee
GO
if exists ( select * from sysobjects where id = object_id ( ' Department ' ) and type = ' u ' )
drop table Department
GO
create table Department
(
Id int primary key ,
Department varchar ( 10 )
)
create table Employee
(
EmployeeId int primary key ,
DepartmentId int Foreign Key (DepartmentId) References Department(Id) , -- DepartmentId ,
EmployeeName varchar ( 10 )
)
create table EmployeeType
(
EmployeeId int Foreign Key (EmployeeId) References Employee(EmployeeId) , -- EmployeeId ,
EmployeeType varchar ( 10 )
)

描述部門,員工和員工類型之間的關(guān)系。
插入測(cè)試數(shù)據(jù)
復(fù)制代碼 代碼如下:

insert Department values ( 1 , ' A ' );
insert Department values ( 2 , ' B ' );
insert Employee values ( 1 , 1 , ' Bob ' );
insert Employee values ( 2 , 1 , ' John ' );
insert Employee values ( 3 , 1 , ' May ' );
insert Employee values ( 4 , 2 , ' Tom ' );
insert Employee values ( 5 , 2 , ' Mark ' );
insert Employee values ( 6 , 2 , ' Ken ' );
insert EmployeeType values ( 1 , ' 正式 ' );
insert EmployeeType values ( 2 , ' 臨時(shí) ' );
insert EmployeeType values ( 3 , ' 正式 ' );
insert EmployeeType values ( 4 , ' 正式 ' );
insert EmployeeType values ( 5 , ' 辭退 ' );
insert EmployeeType values ( 6 , ' 正式 ' );

看一下部門、員工和員工類型的列表
Department EmployeeName EmployeeType
---------- ------------ ------------
A Bob 正式
A John 臨時(shí)
A May 正式
B Tom 正式
B Mark 辭退
B Ken 正式
現(xiàn)在我們需要輸出這樣一個(gè)列表
部門編號(hào) 部門名稱 合計(jì) 正式員工 臨時(shí)員工 辭退員工
這個(gè)問題我的思路是首先統(tǒng)計(jì)每個(gè)部門的員工類型總數(shù)
這個(gè)比較簡(jiǎn)單,我把它做成一個(gè)視圖
復(fù)制代碼 代碼如下:

if exists ( select * from sysobjects where id = object_id ( ' VDepartmentEmployeeType ' ) and type = ' v ' )
drop view VDepartmentEmployeeType
GO
create view VDepartmentEmployeeType
as
select Department.Id, Department.Department, EmployeeType.EmployeeType, count (EmployeeType.EmployeeType) Cnt
from Department, Employee, EmployeeType where
Department.Id = Employee.DepartmentId and Employee.EmployeeId = EmployeeType.EmployeeId
group by Department.Id, Department.Department, EmployeeType.EmployeeType
GO

現(xiàn)在 select * from VDepartmentEmployeeType
Id Department EmployeeType Cnt
----------- ---------- ------------ -----------
2 B 辭退 1
1 A 臨時(shí) 1
1 A 正式 2
2 B 正式 2
有了這個(gè)結(jié)果,我們?cè)偻ㄟ^行列轉(zhuǎn)換,就可以實(shí)現(xiàn)要求的輸出了
行列轉(zhuǎn)換采用 case 分支語句來實(shí)現(xiàn),如下:
復(fù)制代碼 代碼如下:

select Id as ' 部門編號(hào) ' , Department as ' 部門名稱 ' ,
[ 正式 ] = Sum ( case when EmployeeType = ' 正式 ' then Cnt else 0 end ),
[ 臨時(shí) ] = Sum ( case when EmployeeType = ' 臨時(shí) ' then Cnt else 0 end ),
[ 辭退 ] = Sum ( case when EmployeeType = ' 辭退 ' then Cnt else 0 end ),
[ 合計(jì) ] = Sum ( case when EmployeeType > '' then Cnt else 0 end )
from VDepartmentEmployeeType
GROUP BY Id, Department

看一下結(jié)果
部門編號(hào) 部門名稱 正式 臨時(shí) 辭退 合計(jì)
----------- ---------- ----------- ----------- ----------- -----------
1 A 2 1 0 3
2 B 2 0 1 3
現(xiàn)在還有一個(gè)問題,如果員工類型不可以應(yīng)編碼怎么辦?也就是說我們?cè)趯懗绦虻臅r(shí)候并不知道有哪些員工類型。這確實(shí)是一個(gè)
比較棘手的問題,不過不是不能解決,我們可以通過拼接SQL的方式來解決這個(gè)問題。看下面代碼
復(fù)制代碼 代碼如下:

DECLARE
@s VARCHAR ( max )
SELECT @s = isnull ( @s + ' , ' , '' ) + ' [ ' + ltrim (EmployeeType) + ' ] = ' +
' Sum(case when EmployeeType = ''' +
EmployeeType + ''' then Cnt else 0 end) '
FROM ( SELECT DISTINCT EmployeeType FROM VDepartmentEmployeeType ) temp
EXEC ( ' select Id as 部門編號(hào), Department as 部門名稱, ' + @s +
' ,[合計(jì)]= Sum(case when EmployeeType > '''' then Cnt else 0 end) ' +
' from VDepartmentEmployeeType GROUP BY Id, Department ' )

執(zhí)行結(jié)果如下:
部門編號(hào) 部門名稱 辭退 臨時(shí) 正式 合計(jì)
----------- ---------- ----------- ----------- ----------- -----------
1 A 0 1 2 3
2 B 1 0 2 3
這個(gè)結(jié)果和前面硬編碼的結(jié)果是一樣的,但我們通過程序來獲取了所有的員工類型,這樣做的好處是如果我們新增了一個(gè)員工類型,比如“合同工”,我們不需要修改程序,就可以得到我們想要的輸出。

如果你的數(shù)據(jù)庫是SQLSERVER 2005 或以上,也可以采用SQLSERVER2005 通過的新功能 PIVOT
復(fù)制代碼 代碼如下:

SELECT Id as ' 部門編號(hào) ' , Department as ' 部門名稱 ' , [ 正式 ] , [ 臨時(shí) ] , [ 辭退 ]
FROM
( SELECT Id,Department,EmployeeType,Cnt
FROM VDepartmentEmployeeType) p
PIVOT
( SUM (Cnt)
FOR EmployeeType IN ( [ 正式 ] , [ 臨時(shí) ] , [ 辭退 ] )
) AS unpvt

結(jié)果如下
部門編號(hào) 部門名稱 正式 臨時(shí) 辭退
----------- ---------- ----------- ----------- -----------
1 A 2 1 NULL
2 B 2 NULL 1
NULL 可以通過 ISNULL 函數(shù)來強(qiáng)制轉(zhuǎn)換為0,這里我就不寫出具體的SQL語句了。這個(gè)功能感覺還是不錯(cuò),不過合計(jì)好像用這種方法不太好搞。不知道各位同行有沒有什么好辦法。
您可能感興趣的文章:
  • mysql 行轉(zhuǎn)列和列轉(zhuǎn)行實(shí)例詳解
  • mssql 數(shù)據(jù)庫表行轉(zhuǎn)列,列轉(zhuǎn)行終極方案
  • SQL行轉(zhuǎn)列和列轉(zhuǎn)行代碼詳解
  • sql語句實(shí)現(xiàn)行轉(zhuǎn)列的3種方法實(shí)例
  • SQLServer行轉(zhuǎn)列實(shí)現(xiàn)思路記錄
  • MySQL存儲(chǔ)過程中使用動(dòng)態(tài)行轉(zhuǎn)列
  • 數(shù)據(jù)庫實(shí)現(xiàn)行列轉(zhuǎn)換(mysql示例)
  • 深入SQL中PIVOT 行列轉(zhuǎn)換詳解
  • mysql 列轉(zhuǎn)行,合并字段的方法(必看)
  • SQL行轉(zhuǎn)列、列轉(zhuǎn)行的簡(jiǎn)單實(shí)現(xiàn)

標(biāo)簽:美容院 珠海 呼和浩特 天水 商洛 福建 泉州 西寧

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換語句》,本文關(guān)鍵詞  一個(gè),簡(jiǎn)單,的,SQL,行列,轉(zhuǎn)換,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換語句》相關(guān)的同類信息!
  • 本頁收集關(guān)于一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換語句的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章