Отобразить горизонтальные строки вертикально SQL Server 2005 - PullRequest
1 голос
/ 29 февраля 2012

когда я запускаю оператор выбора как

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 для вышеуказанного запроса.

Ответы [ 2 ]

1 голос
/ 29 февраля 2012

Может быть что-то вроде этого:

Первые тестовые данные:

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
0 голосов
/ 29 февраля 2012

Во-первых, вопрос «Строки в столбцы» возникает постоянно, и я обычно рекомендую 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

Этот ответ является ОЧЕНЬ грубым подтверждением концепции, напримерможет использовать аналогичную логику для динамического построения команды PIVOT, которая будет выполнять НАМНОГО лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...