Мое требование похоже на этот вопрос и ответ PostgreSQL — вычислить SUM() of COUNT() Но нужна сумма по другому столбцу
у меня есть что-то похожее на это
create table Item
(
ItemID INTEGER not null,
ItemCode NCHAR(10) not null,
ItemName NCHAR(10) not null,
constraint PK_ITEM primary key (ItemID)
);
create table Store
(
StoreID INTEGER not null,
StoreName NCHAR(20) not null,
ItemID INTEGER not null,
Location NCHAR(20) not null,
constraint PK_STORE primary key (StoreID),
foreign key (ItemID) references Item(ItemID)
);
insert into Item (ItemID,ItemCode,ItemName) Values (1,'abc','abc');
insert into Item (ItemID,ItemCode,ItemName) Values (2,'def','def');
insert into Item (ItemID,ItemCode,ItemName) Values (3,'ghi','ghi');
insert into Store (StoreID,StoreName,ItemID,Location) Values (1,'B1',1,'L1');
insert into Store (StoreID,StoreName,ItemID,Location) Values (2,'B2',2,'L2');
insert into Store (StoreID,StoreName,ItemID,Location) Values (3,'B3',1,'L3');
insert into Store (StoreID,StoreName,ItemID,Location) Values (4,'B4',2,'L1');
insert into Store (StoreID,StoreName,ItemID,Location) Values (5,'B5',3,'L2');
insert into Store (StoreID,StoreName,ItemID,Location) Values (6,'B6',2,'L3');
insert into Store (StoreID,StoreName,ItemID,Location) Values (7,'B7',3,'L1');
insert into Store (StoreID,StoreName,ItemID,Location) Values (8,'B8',1,'L3');
insert into Store (StoreID,StoreName,ItemID,Location) Values (9,'B9',2,'L1');
я пробовал это
select count(I.ItemID), S.ItemID, I.ItemCode, count(S.Location),S.Location
from Store S, Item I where S.ItemId=I.ItemID
group by S.ItemID, I.ItemCode, S.Location ;
Это приводит к этому
Я хочу что-то вроде этого, где общая сумма отображается для itemId
или желательно вот так
Как этого добиться?
Вы можете разделить выборки в одном запросе и объединить результаты, используя join
или union
. Для первого ожидаемого результата вы можете запросить, как показано ниже.
select sq1.count, sq1.ItemID, sq2.ItemCode, sq2.count, sq2.Location from (
select S1.ItemID, count(*) as count
from Store S1
group by S1.ItemID
) sq1
inner join (
select S2.ItemID, I.ItemCode, Count(*), S2.Location from Store S2
inner join Item I
on S2.ItemId = I.ItemId
group by S2.ItemID, I.ItemCode, S2.Location
) sq2
on sq1.ItemID = sq2.ItemID
order by sq2.ItemID, sq2.ItemCode;
Для второго результата вы можете использовать этот запрос
select * from (
select S.ItemID, I.ItemCode, Count(*), S.Location from Store S
inner join Item I
on S.ItemId = I.ItemId
group by S.ItemID, I.ItemCode, S.Location
union
select S2.ItemID, 'Total' as itemcode, Count(*), null
from Store S2
group by S2.ItemID
) sq
order by sq.ItemID, sq.ItemCode;
Вы можете использовать предложение ROLLUP:
select I.ItemID, case when S.Location is null then 'Total' else I.ItemCode end as ItemCode, count(*) as count, S.Location
from #Store S
inner join
#Item I
on S.ItemId=I.ItemID
group by I.ItemID,I.ItemCode, rollup(S.Location)
order by I.ItemId, S.Location NULLS LAST
Но вы должны убедиться, что S.Location не будет иметь нулевых значений (потому что я использовал его для пометки строки промежуточного итога).
Честно говоря, промежуточные и общие итоги и т. д. лучше обрабатываются на уровне представления (инструмент отчетности, форма и т. д.), поскольку механизмы SQL имеют ограниченные возможности для работы с множеством вариантов отображения, которые могут запросить пользователи.
Следующий запрос использует GROUPING SETS
для достижения предпочтительных результатов ОП:
SELECT
s.itemid,
COALESCE(i.itemcode, 'Total') AS itemcode,
COUNT(i.itemid),
COUNT(s.location),
s.location
FROM
store s
JOIN item i ON s.itemid = i.itemid
GROUP BY
GROUPING sets ((s.itemid, i.itemcode, s.location), (s.itemid))
ORDER BY
s.itemid,
s.location;
Это умно! Кажется, что все эти столбцы никогда не соответствуют
NULL
согласно определению таблицы.