Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show SQL result in horizontal format

All I want is to transform this:

Period  | Department    | Print | Copy
---------------------------------------
201601  | Dept 1        | 10    | 20
201601  | Dept 2        | 20    | 10
201602  | Dept 1        | 30    | 40
201602  | Dept 2        | 40    | 30
201603  | Dept 1        | 50    | 60
201603  | Dept 2        | 60    | 50

into this:

Department  | 201601 Print  | 201601 Copy   | 201602 Print  | 201602 Copy   | 201603 Print  | 201603 Copy
------------------------------------------------------------------------------------------
Dept 1      | 10            | 20            | 30            | 40            | 50            | 60
Dept 2      | 20            | 10            | 40            | 30            | 60            | 50

I was trying to build the script with PIVOT but I don't know how to show both "Print" and "Copy" of each period in the columns. Besides, since the values of 'Period' would be unknown therefore I cannot hard-code the value in the script as well.

Here is my attempt:

SELECT [Department]
    ,[201601] AS [201601 Copy]
    ,[201602] AS [201602 Copy]
    ,[201603] AS [201603 Copy]
FROM
    (SELECT [Copy], [Period], [Department] from #tempTable) AS ST
PIVOT
    (SUM([Copy]) FOR [Period] IN ([201601],[201602],[201603])) AS PT

And here is the script for creating the table with my sample data:

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
    DROP TABLE #tempTable
CREATE TABLE #tempTable(
    [Period] varchar(50)
    ,[Department] varchar(50)   
    ,[Print] int
    ,[Copy] int
)
INSERT INTO #tempTable VALUES 
     ('201601', 'Dept 1', 10, 20)
    ,('201601', 'Dept 2', 20, 10)
    ,('201602', 'Dept 1', 30, 40)
    ,('201602', 'Dept 2', 40, 30)
    ,('201603', 'Dept 1', 50, 60)
    ,('201603', 'Dept 2', 60, 50)

Thanks for any reply in advance.

ANSWER

I studied the answers received and finally build the below script:

DECLARE @sql AS varchar(max);
SELECT @sql = 'SELECT [Department],' + 
    STUFF((
        SELECT DISTINCT
            ',SUM(ISNULL(CASE [Period] WHEN ''' + [Period] + ''' THEN [Print] END, 0)) AS [' + [period] + ' Print]' +
            ',SUM(ISNULL(CASE [Period] WHEN ''' + [Period] + ''' THEN [Copy]  END, 0)) AS [' + [period] + ' Copy]'
        FROM #TempTable
        FOR XML PATH('')
    ), 1, 1, '') +
    'FROM #TempTable 
    GROUP BY [Department]';
PRINT @sql
EXEC(@sql);
like image 599
pblyt Avatar asked Mar 07 '17 08:03

pblyt


People also ask

How do I change vertical row to horizontal in SQL?

You can use the PIVOT function to convert your rows of data into columns. Your original query can be used to retrieve all the data, the only change I would make to it would be to exclude the column b. field_id because this will alter the final display of the result.

How do I show a SQL result vertically?

You can output query results vertically instead of a table format. Just type \G instead of a ; when you end you queries in mysql prompt.

How do I count horizontally in SQL?

To count horizontally, you don't use the COUNT function. Instead use the SUM function and the CASE expression. CASE has two forms. You may have more than one WHEN-THEN combo in either form, but for counting, one WHEN-THEN is sufficient.

How display all rows and columns in SQL?

SELECT * FROM <TableName>; This SQL query will select all columns and all rows from the table. For example: SELECT * FROM [Person].


1 Answers

You can use a dynamic sql query.

Query

declare @sql as varchar(max);
select @sql = 'select [Department],' + stuff((
    select distinct ',max(case [Period] when ' + char(39) + [Period] + char(39) + 
    ' then [Print] end) [' + [period] + ' Print]'
    + ',max(case [Period] when ' + char(39) + [Period] + char(39) + 
    ' then [Copy] end) [' + [period] + ' Copy]'
    from #TempTable
    for xml path('')
), 1, 1, '');

select @sql += ' from #TempTable group by [Department];';
exec(@sql);
like image 63
Ullas Avatar answered Sep 20 '22 13:09

Ullas