0

The below query get the following out put.

Service Date  Product1 Product2 
01/Jun/2015    1           3
02/Jun/2015    2           5

Instead of that i want the date to be in the columns so out put should be like this.

Products  01/Jun/2015  02/Jun/2015 
Product1    1           3
Product2    2           5

Query

DECLARE @cols AS nvarchar(max),
        @query AS nvarchar(max)
SELECT
  @cols = STUFF((SELECT
    ',' + QUOTENAME(Product_Name)
  FROM dbo.Store where CatID='2'

  GROUP BY Product_Name
  ORDER BY Product_Name
  FOR xml PATH (''), TYPE)
  .value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET @query = 'SELECT Replace(CONVERT(NVARCHAR, Service_Date, 106), '' '', ''/'') AS [Service Date],' + @cols + ' from ( select Service.Service_Date, Store.Product_Name, Servicelist.ProductQty FROM   dbo.Service INNER JOIN dbo.Servicelist ON dbo.Service.Service_ID = dbo.Servicelist.Service_ID INNER JOIN dbo.Store ON dbo.Servicelist.Pro_ID = dbo.Store.Pro_ID) x pivot ( SUM(ProductQty) for Product_Name in (' + @cols + ') ) p '
EXECUTE (@query);
Ayman
  • 99
  • 1
  • 3
  • 12

2 Answers2

0

Your current query is pivoting product names and grouping the dates. But you need to pivot the dates and group the product names

Try this way

DECLARE @cols  AS NVARCHAR(max),
        @query AS NVARCHAR(max)

Find the distinct list of dates instead of product names

SELECT @cols = Stuff((SELECT ','
                             + Quotename(CONVERT(char(11), Service_Date, 106))
                      FROM   dbo.Store
                      WHERE  CatID = '2'
                      GROUP  BY CONVERT(char(11), Service_Date, 106)
                      ORDER  BY CONVERT(date, Service_Date)
                      FOR xml PATH (''), TYPE) .value('.', 'NVARCHAR(MAX)'), 1, 1, '')

In pivot for list use the Service_date column instead of Product_Name

SET @query = 'SELECT Product_Name,'
             + @cols
             + ' from ( select Service.Service_Date, Store.Product_Name, Servicelist.ProductQty FROM   dbo.Service INNER JOIN dbo.Servicelist ON dbo.Service.Service_ID = dbo.Servicelist.Service_ID INNER JOIN dbo.Store ON dbo.Servicelist.Pro_ID = dbo.Store.Pro_ID) x pivot ( SUM(ProductQty) for CONVERT(char(11), Service_Date, 106) in ('
             + @cols + ') ) p '

EXECUTE (@query); 
Pரதீப்
  • 91,748
  • 19
  • 131
  • 172
0

This is how it's done using plain ANSI SQL.

First, you need to pivot vertically - UNPIVOT in TRANSACT-SQL speak - which you do by CROSS JOINing with a single-column temp table with as many consecutive integers as you have values to "unpivot". You use those integers as indexes in a CASE WHEN expression for the values.

Then, you re-pivot, using a SUM(CASE WHEN ...) expression, and GROUP BY the column whose values you want to see vertically in the first column.

Here goes:

WITH
-- input
input(Service_Date,Product1,Product2) AS (
          SELECT DATE '2015-06-01',1,3
UNION ALL SELECT DATE '2015-06-02',2,5
)          
,
-- start vertical pivot: two integers
two_ints(idx) AS (SELECT 1 UNION ALL SELECT 2)
,
-- vertical pivot: CROSS JOIN input with two integers
vert_pivot AS (
SELECT
  Service_Date
, idx
, 'Product'||CAST(idx AS CHAR(1)) AS product
, CASE idx WHEN 1 THEN Product1 WHEN 2 THEN Product2 END AS qty
FROM input CROSS JOIN two_ints
)
-- debug
-- SELECT * FROM vert_pivot;
-- Service_Date|idx|product |qty
-- 2015-06-01  |  1|Product1|  1
-- 2015-06-01  |  2|Product2|  3
-- 2015-06-02  |  1|Product1|  2
-- 2015-06-02  |  2|Product2|  5
,
-- re-pivot horizontally by date
horiz_pivot_dt AS (
SELECT
  product
, SUM(CASE Service_Date WHEN '2015-06-01' THEN qty END) AS "2015-06-01"
, SUM(CASE Service_Date WHEN '2015-06-02' THEN qty END) AS "2015-06-02"
FROM vert_pivot
GROUP BY
  product
)
SELECT * FROM horiz_pivot_dt
;
-- result:
-- product |2015-06-01|2015-06-02
-- Product1|         1|         2
-- Product2|         3|         5

by the way: I noted that you only pivoted the "column names" and the first column's values - not the measures. My example above did, and I spent a few minutes trying to find out where my error was ....

Happy playing ... marco

marcothesane
  • 6,192
  • 1
  • 11
  • 21