#sql #sql-server-2008 #pivot
#sql #sql-server-2008 #сводные
Вопрос:
Я застрял на конкретной проблеме, я надеюсь, что кто-нибудь сможет мне помочь. У меня есть четыре таблицы Product, ProductType, Orders. Я хочу просмотреть данные из таблицы заказов, но хочу просмотреть их таким образом, чтобы каждый день данные группировались по сумме количества проданного товара за каждый день под каждым типом продукта. Пожалуйста, просмотрите структуру таблицы, я попытался получить группы продуктов в виде списка массивов и могу суммировать количество продуктов для каждой группы типов продуктов, но не могу понять, как просмотреть это таким образом, чтобы каждая группа типов продуктов отображалась в виде суммы для каждой даты в виде отдельного столбца,Мне сказали, что сводный или перекрестный запрос табуляции может это сделать, я смог создать массив с разделителями-запятыми в SQL, но для поиска данных в списке типов продуктов мне пришлось создать временную таблицу и использовать функцию, описанную здесь http://databases.aspfaq.com/database/how-do-i-simulate-an-array-inside-a-stored-procedure.html чтобы найти совпадающие значения…но не знаю, как получить желаемое представление, я должен использовать массив или какой-то динамический список, потому что я не знаю, сколько может быть столбцов группы типов продуктов?
Ваша помощь была бы очень признательна, заранее спасибо!!
Порядок таблиц
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
Табличные продукты
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
Тип продукта таблицы
TypeID Name Desc
1 Fruits Fresh Fruits
2 Vegetables Fresh Veggies
3 Kitchen Kitchen stuff
Расположение хранилища таблиц
loc_id city state
1 Atlanta GA
2 New york NY
3 Chicago IL
Желаемый вид проданных продуктов суммируется и группируется по типу продукта каждый день * Пожалуйста, имейте в виду, что это всего лишь образец, поэтому я не могу группировать по идентификатору типа proudct (1,2,3) в моей реальной проблеме могут быть сотни групп типов продуктов, поэтому список столбцов должен генерироваться динамически
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. Что вы используете? MySQL или MS SQL Server?
2. ОК. Я собирался помочь вам с MySQL;-)
Ответ №1:
Вот как я бы это сделал:
/*
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)
Вот расширение, использующее операторы case:
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)
Комментарии:
1. Привет, Михал, спасибо за ваш ответ, я получил ваше предложение поработать с количеством, но у меня есть еще один или два вопроса 🙂 1) Если я хочу отобразить сумму для другого столбца, кроме количества, просто для примера, скажем, SUM (Store_locID), как я мог это сделать, я пытался сделать PIVOT ( SUM (Количество) для имени в (‘ @columns ‘), СУММА (Store_locID) для имени в (‘ @columns ‘) ) СВОДНЫЕ ДАННЫЕ» но это не позволяет мне добавлять какие-либо дополнительные столбцы, для которых я хотел бы увидеть сумму? 2) Как я мог бы использовать псевдоним или переименовать столбцы количества суммы для, например, овощей (сумма), фруктов (сумма) и т. Д
2. Вы не можете сделать это в одном сводном операторе, ограничение заключается в том, что вы можете использовать только одну агрегацию. Что вы могли бы сделать, это выполнить 2 из этих инструкций, а затем объединить их на основе даты и типа продукта. Или вы могли бы перезаписать оператор PIVOT, используя оператор case.
3. Я добавил статусы обращения, так что вам нужно только добавить желаемый агрегат в переменную @column
4. хм, хорошо, когда я делаю join, он жалуется, что столбцы в верхнем списке неоднозначны… Пожалуйста, имейте в виду, что группы типов продуктов являются общими для обоих элементов, для которых я пытаюсь показать сумму, давайте назовем их ProductBoxes, например, sake… они используют одни и те же типы продуктов, поэтому имена столбцов будут одинаковыми, если я не создам другой список @columns и не назову типы продуктов в этом другом, может быть?