2012-02-03 52 views
2

給定一個表是這樣的:`PIVOT`用`EXISTS`

[Last Name] [First Name] [DepartmentID] 
--------------------------------------- 
Doe   John   1 
Doe   John   2 
Black  Frank  3 

,我想這樣的結果:

[Last Name] [First Name] [Accounting] [Management] [Development] 
---------------------------------------------------------------- 
Doe   John   X   X 
Black  Frank         X 

到目前爲止,我有這樣的查詢:

SELECT [Last Name], [First Name], [1], [2], [3] 
FROM Employees 
PIVOT(SUM(DepartmentID) FOR DepartmentID IN ([1], [2], [3]) 
GROUP BY [Last Name], [First Name], [1], [2], [3] 

這給了我:

[Last Name] [First Name] [1] [2] [3] 
---------------------------------------------------------------- 
Doe   John   1 
Doe   John    2 
Black  Frank    3 

幾個問題:

  • 列名稱來自別處,即應當從函數或子查詢的。這可以做到嗎?
  • 我假設我將不得不使用動態SQL來獲取可能的部門,即我不能告訴PIVOT只是確定所有可能性?
  • 列值應該是'X'(或類似),不包含實際值。每個可能的部門不應該有多行,這意味着我無法通過樞軸列進行分組。我如何獲得每人一行?

我真的不想要或不需要聚合任何東西;我只是希望根據每個部門展示該員工是否居住在該部門。是PIVOT這個紅鯡魚嗎?我可以用更復雜的方式解決這個問題,每個部門有EXISTS聲明?

+1

您應該刪除'GROUP BY [姓氏],[名],[1] ,[2],[3]'位。這是毫無意義的。順便說一句,你必須在你的表中有一個額外的列,你沒有向我們顯示像導致多行問題的「RecordId」。 [每位員工只返回1行](http://data.stackexchange.com/stackoverflow/query/60760/new) – 2012-02-03 17:57:06

+0

確實有更多的列,它們可能會有所不同。你也是正確的,PIVOT似乎意味着GROUP BY。 – 2012-02-03 18:21:43

+0

解決方法是使用CTE或派生表作爲僅包含3列感興趣的PIVOT源。你可以使用'CASE'語句來獲得你的'X'而不是數字。如果列列表是動態的,則需要動態SQL。 – 2012-02-03 18:24:41

回答

9

也許這將幫助:

首先是一些測試數據:

CREATE TABLE tbl(LastName VARCHAR(100),FirstName VARCHAR(100),DepartmentID INT) 
CREATE TABLE tblDepartment(DepartmentID INT,Name VARCHAR(100)) 

INSERT INTO tbl 
SELECT 'Doe','John',1 UNION ALL 
SELECT 'Doe','John',2 UNION ALL 
SELECT 'Black','Frank',3 

INSERT INTO tblDepartment 
SELECT 1,'Accounting' UNION ALL 
SELECT 2,'Management' UNION ALL 
SELECT 3,'Development' 

的concating列:

DECLARE @cols VARCHAR(MAX) 
SELECT @cols = COALESCE(@cols + ','+QUOTENAME(Name), 
        QUOTENAME(Name)) 
FROM 
    tblDepartment 
ORDER BY 
    Name 

或者你可能想Concat的只用現有的列像這樣:

DECLARE @cols VARCHAR(MAX) 
SELECT @cols = COALESCE(@cols + ','+QUOTENAME(Name), 
        QUOTENAME(Name)) 
FROM 
    tblDepartment 
WHERE EXISTS 
     (
      SELECT 
       NULL 
      FROM 
       tbl AS tbl2 
      WHERE 
       tblDepartment.DepartmentID=tbl2.DepartmentID) 
ORDER BY 
    Name 

然後執行動態SQL:

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     tbl.LastName, 
     tbl.FirstName, 
     Department.Name, 
     ''X'' as test 
    FROM 
     tbl AS tbl 
     JOIN tblDepartment AS Department 
      ON Department.DepartmentID=tbl.DepartmentID 
)AS p 
PIVOT 
(
    MAX(test) FOR Name IN ('[email protected]+') 
) As Pvt' 

EXECUTE(@query) 

而在我的情況下丟棄創建的表:

DROP TABLE tbl 
DROP TABLE tblDepartment 
+2

+1;你也可以用'QUOTENAME'(Name,'[')''替換''['+ Name +']''' – 2012-02-04 12:39:01

+0

不知道。這很乾淨。謝謝。更新anser。 – Arion 2012-02-04 13:16:25

+0

或者我可以使用QUOTENAME(Name),因爲默認值是'[',第二個參數不是必需的。 – Arion 2012-02-04 13:22:40