У меня есть 2 таблицы в sql-server 2005 express DB
1. Таблица размеров товара
CREATE TABLE [dbo].[ItemSize](
[ID] [int] IDENTITY(1,1) NOT NULL,
[iSize] [int] NULL
) ON [PRIMARY]
2. Таблица SalesLog
CREATE TABLE [dbo].[SalesLog](
[SalesID] [int] IDENTITY(1,1) NOT NULL,
[MemoNo] [int] NULL,
[ProductCode] [int] NULL,
[Quantity] [int] NULL,
[Price] [int] NULL,
[pGroup] [int] NULL,
[pName] [nvarchar](30) NULL,
[pSize] [int] NULL,
[BillDate] [nchar](10) NULL,
CONSTRAINT [PK_SalesLog] PRIMARY KEY CLUSTERED
(
[SalesID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Таблица ItemSize содержит напитки разного размера лайк
100 мл
200 мл
300 мл
400 мл
500 мл
Я хочу, чтобы данные столбцов таблицы ItemSize (iSize) были столбцами типа
ItemName 100ml 200ml 300ml 400ml 500ml
Drink A 10 20 5 4 30
Drink B 20 10 15 35 40
и данные будут упорядочены из таблицы продаж в соответствии с размером и названием продукта, как показано выше.
У меня есть аналогичный запрос, но он не динамический. Я имею в виду, что если я добавлю новый размер в таблицу ItemSize, то он не будет доступен для отчета. Поэтому мне нужно решение для этого.
В настоящее время я использую этот запрос для получения данных о продажах по размеру товара.
select i.gName,
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=0 and
pGroup=i.gCode),0) as '0ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=180 and
pGroup=i.gCode),0) as '180ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=375 and
pGroup=i.gCode),0) as '375ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=500 and
pGroup=i.gCode),0) as '500ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=650 and
pGroup=i.gCode),0) as '650ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=750 and
pGroup=i.gCode),0) as '750ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and pSize=1000 and
pGroup=i.gCode),0) as '1000ml',
isnull((select
sum(Quantity)from saleslog where BillDate='01-06-2010' and
pSize=2000 and pGroup=i.gCode),0) as '2000ml'
from saleslog as s
inner join ItemGroup as i on s.pGroup=i.gCode
where BillDate='01-06-2010'
group by i.gCode, i.gName
Вы проверили PIVOT характерная черта? Вы не упоминаете, какую версию SQL вы используете, но она доступна в 2008 году и делает в значительной степени то, что вам нужно.
Кроме того, ваш код кажется ужасно неэффективным. Вы делаете выборки внутри выборок, извлекая данные, к которым у вас уже есть доступ. Может быть, мне сложно идентифицироваться с вашим набором данных, но мне кажется, что в вашей текущей ситуации нужен оператор case, а не множество выборок. Я считаю, что следующие работы:
select
i.gName,
case i.pSize when 0 then sum(Quantity) else 0 end as [0ml],
case i.pSize when 180 then sum(Quantity) else 0 end as [180ml],
case i.pSize when 375 then sum(Quantity) else 0 end as [375ml],
{ rest of case samples }
from
saleslog as s
inner join ItemGroup as i on s.pGroup = i.gGroup
where
s.BillDate = '01-06-2010'
group by
i.gName
Я тоже немного запутался в вашем вопросе. Вы упомянули, что у вас есть две таблицы, у одной есть идентификатор и iSize, но я не вижу iSize, поэтому я предполагаю pSize (?). Кроме того, ваша таблица продаж не соответствует вашему запросу, т. Е. В вашей таблице продаж нет количества, в вашем создании упоминаются [продажи], но ваш фактический запрос использует [salesdata].
Может быть, еще какое-то уточнение?