SQL pivot data with dynamic list of columns

流过昼夜 提交于 2021-01-28 05:53:42

问题


Im stuck on a particular problem im hoping someone can help me out with. I have four tables Product, ProductType, Orders. I want to view Data from the Orders table but want to view it in a way where on each day the data is grouped by the sum of product quantity sold for each day under each ProductType. Please view the table structure, I have tried to get the Product groups as an array list and am able to sum the product quantity up for each product type group but cant figure out how to view this in a way where each producttype group is displayed as a sum for each date as a seperate column, I was told Pivot or a cross tab query could do this, I was able to make a comma delimited array in SQL but in order to find data in the product Type list I had to create a temp table and use a function described here http://databases.aspfaq.com/database/how-do-i-simulate-an-array-inside-a-stored-procedure.html to find matching values...but dont know how to get the view I want, I have to use an array or some dynamic list because I dont know how many product type group columns there could be?

Your help would be greatly appreciated, thanks in advance!!

Table Order

Order ID  ProductID   Quantity  Date      CustomerID    Store_locID
  1          1           5     10/01/2011      12          1
  2          2           10    10/03/2011      4           1
  3          3           8     10/03/2011      5           1
  4          4           11    10/05/2011      4           2
  5          5           5     10/05/2011      14          2
  6          6           8     10/06/2011      3           3

Table Products

ProductID    Name      Desc         ProdTypeID 
  1          Bananas   Chiquita         1
  2          Apples    Green Apples     1
  3          Grapes    Green Grapes     1
  4          Potatoes  Idaho potatoes   2
  5          Brocolli  Green Vrocolli   2
  6          Plates    Paper Plates     3

Table Product Type

 TypeID      Name       Desc   
  1          Fruits     Fresh Fruits
  2          Vegetables Fresh Veggies
  3          Kitchen    Kitchen stuff 

Table Store Locations

loc_id      city        state
   1        Atlanta     GA
   2        New york    NY
   3        Chicago     IL 

Desired View Products sold summed and grouped by Product Type on each day* Please keep in mind this is just a sample so I cant group by proudct type ID (1,2,3) in my real problem there could be hundreds of product Type groups so the list of columns has to be generated dynamically

   City      Date     Fruits (sum)    Vegetables(sum)  Kitchen(sum)   Group4*    Group5*      

  Atlanta    10/01/2011   5                  0               0           0
  Atlanta    10/03/2011   18                 0               0           0
  New York   10/05/2011   0                  16              0           0     
  Chicago    10/06/2011   0                  0               8           0

回答1:


Here is how I would do that:

/*
create table ##order  ( ID int, ProdID int, Quantity int, [Date] date, CustID int, StoreID int );
insert into ##order values (1,1,5,'2011-01-10' ,12,1), (2,2,10,'2011-03-10',4 ,1), (3,3,8,'2011-03-10' ,5 ,1), (4,4,11,'2011-05-10',4 ,2), (5,5,5,'2011-05-10' ,14,2), (6,6,8,'2011-06-10' ,3 ,3);
create table ##product (ProdID int, ProdName varchar(64), ProdDesc varchar(255), ProdType int);
insert into ##product values (1,'Bananas','Chiquita',1), (2,'Apples','Green Apples',1), (3,'Grapes','Green Grapes',1), (4,'Potatoes','Idaho potatoes',2), (5,'Brocolli','Green Brocolli',2), (6,'Plates','Paper Plates',3);
create table ##ProdType (TypeID int, Name varchar(64), [Desc] varchar(255));
insert into ##ProdType values (1,'Fruits','Fresh Fruits'),(2,'Vegetables','Fresh Veggies'),(3,'Kitchen','Kitchen stuff');
create table ##loc (loc_id int, city varchar(50), [state] varchar(50))
insert into ##loc values(1, 'Atlanta','GA'), (2, 'New york', 'NY'), (3, 'Chicago', 'IL');
*/

declare @cmd varchar(max), @columns varchar(max)
set @columns = ''


select @columns = @columns + '['+Name+'],' from ##ProdType order by name asc
select @columns = substring(@columns, 0, len(@columns))

set @cmd = '
select city, date,'+@columns+' from
(
select   
   ct.city,
   ord.Date,
   pt.Name,
   ord.Quantity
from 
   ##order ord 
   join ##product pr on ord.ProdID = pr.ProdID
   join ##ProdType pt on pr.ProdType = pt.TypeID
   join ##loc ct on ord.StoreID = ct.loc_id
)date_to_pivot
PIVOT
(
SUM(Quantity) for Name in ('+@columns+')
)PIVOTED_DATA'   

exec (@cmd)

Here is the extension using the case statements:

set @columns = ''

select @columns = ''
select @columns = @columns + 'sum(case when pt.Name = '''+Name+''' then ord.Quantity else 0 end) as '+Name+'_SUM,' from ##ProdType order by name asc
select @columns = @columns + 'count(case when pt.Name = '''+Name+''' then ord.Quantity else 0 end) as '+Name+'_COUNT,' from ##ProdType order by name asc
select @columns = substring(@columns, 0, len(@columns))


set @cmd = '
select   
   ct.city,
   ord.Date,   '
   +@columns+
'   
from 
   ##order ord 
   join ##product pr on ord.ProdID = pr.ProdID
   join ##ProdType pt on pr.ProdType = pt.TypeID
   join ##loc ct on ord.StoreID = ct.loc_id
group by
   ct.city,
   ord.Date'

   exec (@cmd)


来源:https://stackoverflow.com/questions/7882466/sql-pivot-data-with-dynamic-list-of-columns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!