欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2009年08月29日 16:35:36   作者:  
在數(shù)據(jù)庫開發(fā)中經(jīng)常會遇到行列轉(zhuǎn)換的問題,比如下面的問題,部門,員工和員工類型三張表,我們要統(tǒng)計類似這樣的列表
一個簡單的SQL 行列轉(zhuǎn)換
Author: eaglet
在數(shù)據(jù)庫開發(fā)中經(jīng)常會遇到行列轉(zhuǎn)換的問題,比如下面的問題,部門,員工和員工類型三張表,我們要統(tǒng)計類似這樣的列表
部門編號 部門名稱 合計 正式員工 臨時員工 辭退員工
1 A 30 20 10 1
這種問題咋一看摸不著頭緒,不過把思路理順后再看,本質(zhì)就是一個行列轉(zhuǎn)換的問題。下面我結(jié)合這個簡單的例子來實現(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)系。
插入測試數(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 , ' 臨時 ' );
insert EmployeeType values ( 3 , ' 正式 ' );
insert EmployeeType values ( 4 , ' 正式 ' );
insert EmployeeType values ( 5 , ' 辭退 ' );
insert EmployeeType values ( 6 , ' 正式 ' );

看一下部門、員工和員工類型的列表
Department EmployeeName EmployeeType
---------- ------------ ------------
A Bob 正式
A John 臨時
A May 正式
B Tom 正式
B Mark 辭退
B Ken 正式
現(xiàn)在我們需要輸出這樣一個列表
部門編號 部門名稱 合計 正式員工 臨時員工 辭退員工
這個問題我的思路是首先統(tǒng)計每個部門的員工類型總數(shù)
這個比較簡單,我把它做成一個視圖
復(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 臨時 1
1 A 正式 2
2 B 正式 2
有了這個結(jié)果,我們再通過行列轉(zhuǎn)換,就可以實現(xiàn)要求的輸出了
行列轉(zhuǎn)換采用 case 分支語句來實現(xiàn),如下:
復(fù)制代碼 代碼如下:

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

看一下結(jié)果
部門編號 部門名稱 正式 臨時 辭退 合計
----------- ---------- ----------- ----------- ----------- -----------
1 A 2 1 0 3
2 B 2 0 1 3
現(xiàn)在還有一個問題,如果員工類型不可以應(yīng)編碼怎么辦?也就是說我們在寫程序的時候并不知道有哪些員工類型。這確實是一個
比較棘手的問題,不過不是不能解決,我們可以通過拼接SQL的方式來解決這個問題??聪旅娲a
復(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 部門編號, Department as 部門名稱, ' + @s +
' ,[合計]= Sum(case when EmployeeType <> '''' then Cnt else 0 end) ' +
' from VDepartmentEmployeeType GROUP BY Id, Department ' )

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

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

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

結(jié)果如下
部門編號 部門名稱 正式 臨時 辭退
----------- ---------- ----------- ----------- -----------
1 A 2 1 NULL
2 B 2 NULL 1
NULL 可以通過 ISNULL 函數(shù)來強制轉(zhuǎn)換為0,這里我就不寫出具體的SQL語句了。這個功能感覺還是不錯,不過合計好像用這種方法不太好搞。不知道各位同行有沒有什么好辦法。

相關(guān)文章

  • 如何控制SQLServer中的跟蹤標(biāo)記

    如何控制SQLServer中的跟蹤標(biāo)記

    對于DBA來說,掌握Trace Flag是一個成為SQL Server高手的必要條件之一,在大多數(shù)情況下,Trace Flag只是一個劍走偏鋒的奇招,不必要,但在很多情況下,會使用這些標(biāo)記可以讓你更好的控制SQL Server的行為
    2013-08-08
  • MyBatis實踐之動態(tài)SQL及關(guān)聯(lián)查詢

    MyBatis實踐之動態(tài)SQL及關(guān)聯(lián)查詢

    MyBatis,大家都知道,半自動的ORM框架,原來叫ibatis,后來好像是10年apache軟件基金組織把它托管給了goole code,就重新命名了MyBatis,功能相對以前更強大了。本文給大家介紹MyBatis實踐之動態(tài)SQL及關(guān)聯(lián)查詢,對mybatis動態(tài)sql相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-03-03
  • SQL查詢字段被包含語句

    SQL查詢字段被包含語句

    說到SQL的模糊查詢,最先想到的,應(yīng)該就是like關(guān)鍵字。當(dāng)我們需要查詢包含某個特定字段的數(shù)據(jù)時,往往會使用 ‘%關(guān)鍵字%’ 查詢的方式。具體代碼示例大家參考下本文
    2017-07-07
  • SQLSERVER對索引的利用及非SARG運算符認識

    SQLSERVER對索引的利用及非SARG運算符認識

    SQL對篩選條件簡稱:SARG(search argument/SARG)當(dāng)然這里不是說SQLSERVER的where子句,是說SQLSERVER對索引的利用,感興趣的朋友可以了解下,或許本文的知識點對你有所幫助哈
    2013-02-02
  • 將Session值儲存于SQL Server中

    將Session值儲存于SQL Server中

    將Session值儲存于SQL Server中...
    2007-03-03
  • SQL?Server還原完整備份和差異備份的操作過程

    SQL?Server還原完整備份和差異備份的操作過程

    這篇文章主要介紹了SQL?Server?還原?完整備份和差異備份的詳細操作,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • SQL Server 在分頁獲取數(shù)據(jù)的同時獲取到總記錄數(shù)

    SQL Server 在分頁獲取數(shù)據(jù)的同時獲取到總記錄數(shù)

    本文通過兩種方法給大家介紹SQL Server 在分頁獲取數(shù)據(jù)的同時獲取到總記錄數(shù),感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • SQLite之Autoincrement關(guān)鍵字(自動遞增)

    SQLite之Autoincrement關(guān)鍵字(自動遞增)

    SQLite 的 AUTOINCREMENT 是一個關(guān)鍵字,用于表中的字段值自動遞增,關(guān)鍵字 AUTOINCREMENT 只能用于整型(INTEGER)字段。
    2015-10-10
  • sql高級技巧幾個有用的Sql語句

    sql高級技巧幾個有用的Sql語句

    sql語句對于數(shù)據(jù)的一些操作,根據(jù)另外一個表的內(nèi)容修改第一個表的內(nèi)容
    2008-08-08
  • sql?server自動生成拼音首字母的函數(shù)

    sql?server自動生成拼音首字母的函數(shù)

    建立一個查詢,執(zhí)行語句生成函數(shù)fn_GetPy,下面是具體的實現(xiàn),需要的朋友可以參考下
    2014-01-01

最新評論