当我发出像
这样的选择语句时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。
答案 0 :(得分: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
。我在ROW_NUMBER
上使用EMPID
:
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,'+@cols+'
FROM
CTE
PIVOT
(
MAX(Value)
FOR RowId IN('+@cols+')
) AS p'
EXECUTE(@query)
然后在我的情况下,我将删除临时表
DROP TABLE tblTempValues
答案 1 :(得分:0)
首先关闭,“Rows to columns”问题一直出现,我通常会推荐一个PIVOT(),但在这种情况下,你将会有不同数量的“列”。你创造了新员工。所以我不知道如何使用PIVOT()。我能想到的唯一方法是采用基于clunky迭代的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
这个答案是一个非常粗略的概念证明,例如,你可以使用类似的逻辑动态构建一个PIVOT命令,它会更好地执行。