2012-02-29 40 views
1

当我发出Select语句,如显示横排垂直的SQL Server 2005

SELECT EMPID,ENAME,SALARY,DEPARTMENT from EMPLOYEE 

然后数据显示像

EMPID  ENAME SALARY DEPARTMENT 
--------------------------------------------- 
01  TEST1 2000  A/C 
02  TEST2 3000  SALES 

,但现在我想说明它像

EMPID  01  02 

ENAME  TEST1 TEST2 

SALARY  2000 3000 

DEPARTMENT A/C  SALES 

所以如何为上面的查询编写sql。

+1

你希望得到该表有多少行?做做你意识到当你有200个职业球员时,你需要201列?,你为什么需要这个? – Lamak 2012-02-29 14:06:41

+0

你在哪里显示这些结果? – kaj 2012-02-29 14:10:38

回答

1

也许是这样的:

首先是一些测试数据:

CREATE TABLE tblTempValues 
    (
     EMPID VARCHAR(100), 
     ENAME VARCHAR(100), 
     SALARY INT, 
     DEPARTMENT VARCHAR(100) 
    ) 

INSERT INTO tblTempValues 
VALUES 
    ('01','TEST1',2000,'A/C'), 
    ('02','TEST2',3000,'SALES') 

将得到列PIVOT上。我用EMPIDROW_NUMBER在:

DECLARE @cols VARCHAR(MAX) 
;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(ORDER BY tblTempValues.EMPID) AS RowNbr 
    FROM 
     tblTempValues 
) 
SELECT 
    @cols=COALESCE(@cols +','+QUOTENAME(RowNbr),QUOTENAME(RowNbr)) 
FROM 
    CTE 

然后做一个动态的支点这样。该orderWeight,这样你将有列的顺序:

DECLARE @query NVARCHAR(4000)= 
N';WITH CTE 
AS 
(
    SELECT ''EMPID'' AS ID, CAST(EMPID AS VARCHAR(MAX)) AS Value, ROW_NUMBER() OVER(ORDER BY EMPID) AS RowId,1 as orderWeight FROM tblTempValues UNION ALL 
    SELECT ''ENAME'' AS ID, CAST(ENAME AS VARCHAR(MAX)) AS Value, ROW_NUMBER() OVER(ORDER BY EMPID) AS RowId,2 as orderWeight FROM tblTempValues UNION ALL 
    SELECT ''SALARY'' AS ID, CAST(SALARY AS VARCHAR(MAX)) AS Value, ROW_NUMBER() OVER(ORDER BY EMPID) AS RowId,3 as orderWeight FROM tblTempValues UNION ALL 
    SELECT ''DEPARTMENT'' AS ID, CAST(DEPARTMENT AS VARCHAR(MAX)) AS Value, ROW_NUMBER() OVER(ORDER BY EMPID) AS RowId,4 as orderWeight FROM tblTempValues 
) 
SELECT 
    ID,'[email protected]+' 
FROM 
    CTE 
PIVOT 
(
    MAX(Value) 
    FOR RowId IN('[email protected]+') 

) AS p' 

EXECUTE(@query) 

然后在我的情况下,我会下降临时表

DROP TABLE tblTempValues 
+0

+1 - 比我的回答好得多。 – HeavenCore 2012-02-29 17:55:32

+0

谢谢..你的答案也适用。但也许不那么有效。上帝试试.. – Arion 2012-02-29 21:14:02

0

首先,“行列”问题一直出现,我通常会推荐一个PIVOT(),但在这种情况下,您将有不同数量的“列”当你创建新员工时。所以我没有看到PIVOT()如何被使用。我能想到的唯一方法就是使用基于SQL的笨重迭代。

这个答案违背了我的判断,如果你有大量的员工,我的表现会非常糟糕(我不能强调这一点!) - 但是安排在高峰时间或1次报告等等,根据你的情况,这可能就足够了。

--#### Create Dummy Data 
CREATE TABLE [dbo].[tbl_ExampleData](
    [EMPID] [varchar](2) NULL, 
    [ENAME] [varchar](50) NULL, 
    [SALARY] [decimal](18, 0) NULL, 
    [DEPARTMENT] [varchar](50) NULL 
) ON [PRIMARY] 

GO 
SET ANSI_PADDING OFF 
GO 
INSERT [dbo].[tbl_ExampleData] ([EMPID], [ENAME], [SALARY], [DEPARTMENT]) VALUES (N'01', N'TEST1', CAST(2000 AS Decimal(18, 0)), N'A/C') 
GO 
INSERT [dbo].[tbl_ExampleData] ([EMPID], [ENAME], [SALARY], [DEPARTMENT]) VALUES (N'02', N'TEST2', CAST(3000 AS Decimal(18, 0)), N'SALES') 
GO 

--#### Select data as columns 
DECLARE @CrossTabCursor CURSOR 
DECLARE @CursorVal_EmpID VARCHAR(4) 

-- #### Create the Basic Temp Table that we will build the crosstab data in 
CREATE TABLE #tbl_CrossTabExample ([-] VARCHAR(50)) 

-- #### Populate the Y axis 
INSERT INTO #tbl_CrossTabExample 
     ([-] 

     ) 
     SELECT 'EMPID' 
     UNION ALL 
     SELECT 'ENAME' 
     UNION ALL 
     SELECT 'SALARY' 
     UNION ALL 
     SELECT 'DEPARTMENT' 


-- #### Add the nessasary columns - in this case, a varchar column per employee 
SET 
@CrossTabCursor = CURSOR FAST_FORWARD FOR 
SELECT [EMPID] FROM [dbo].[tbl_ExampleData] 
OPEN @CrossTabCursor 
FETCH NEXT FROM @CrossTabCursor 
     INTO @CursorVal_EmpID 
WHILE @@FETCH_STATUS = 0 
    BEGIN 
     -- #### Add column to the new table query based on the current cursor position (branch number) 
     EXEC ('ALTER TABLE #tbl_CrossTabExample ADD [' + @CursorVal_EmpID + '] VARCHAR(50) NULL') 

     -- #### Populate the new employee column 
     EXEC ('UPDATE #tbl_CrossTabExample SET [' + @CursorVal_EmpID + '] = (SELECT EMPID FROM [tbl_ExampleData] B WHERE B.EMPID = ''' + @CursorVal_EmpID + ''') WHERE #tbl_CrossTabExample.[-] = ''EMPID''') 
     EXEC ('UPDATE #tbl_CrossTabExample SET [' + @CursorVal_EmpID + '] = (SELECT ENAME FROM [tbl_ExampleData] B WHERE B.EMPID = ''' + @CursorVal_EmpID + ''') WHERE #tbl_CrossTabExample.[-] = ''ENAME''') 
     EXEC ('UPDATE #tbl_CrossTabExample SET [' + @CursorVal_EmpID + '] = (SELECT SALARY FROM [tbl_ExampleData] B WHERE B.EMPID = ''' + @CursorVal_EmpID + ''') WHERE #tbl_CrossTabExample.[-] = ''SALARY''') 
     EXEC ('UPDATE #tbl_CrossTabExample SET [' + @CursorVal_EmpID + '] = (SELECT DEPARTMENT FROM [tbl_ExampleData] B WHERE B.EMPID = ''' + @CursorVal_EmpID + ''') WHERE #tbl_CrossTabExample.[-] = ''DEPARTMENT''') 

     -- #### move onto next branch 
     FETCH NEXT FROM @CrossTabCursor 
       INTO @CursorVal_EmpID 
    END 
CLOSE @CrossTabCursor 
DEALLOCATE @CrossTabCursor 


-- #### Select the completed cross tab data 
SELECT * 
FROM #tbl_CrossTabExample 

-- #### Drop the Temp Table 
DROP TABLE #tbl_CrossTabExample 

这个答案是概念的一个非常粗略的证据,例如,你可以使用类似的逻辑来动态地构建一个转动命令至极将执行好得多。