My requirement is similar to this question & answer PostgreSQL - Calculate SUM() of COUNT() But need the total by another column
I have something similar to this
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');
I have tried this
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 ;
This results in this
count | itemid | itemcode | count | location |
---|---|---|---|---|
2 | 1 | abc | 2 | L3 |
1 | 1 | abc | 1 | L1 |
1 | 2 | def | 1 | L3 |
2 | 2 | def | 2 | L1 |
1 | 2 | def | 1 | L2 |
1 | 3 | ghi | 1 | L2 |
1 | 3 | ghi | 1 | L1 |
I want something like this where the total displayed for itemId
count | itemid | itemcode | count | location |
---|---|---|---|---|
3 | 1 | abc | 2 | L3 |
3 | 1 | abc | 1 | L1 |
4 | 2 | def | 1 | L3 |
4 | 2 | def | 2 | L1 |
4 | 2 | def | 1 | L2 |
2 | 3 | ghi | 1 | L2 |
2 | 3 | ghi | 1 | L1 |
or preferably like this
itemid | itemcode | count | location |
---|---|---|---|
1 | abc | 2 | L3 |
1 | abc | 1 | L1 |
1 | Total | 3 | <------- |
2 | def | 1 | L3 |
2 | def | 2 | L1 |
2 | def | 1 | L2 |
2 | Total | 4 | <------- |
3 | ghi | 1 | L2 |
3 | ghi | 1 | L1 |
3 | Total | 2 | <------- |
How to achieve this?
You can have separated selects in a single query and combine the result using join
or union
. For the first expected output, you can query like below
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;
For the second result, you can use this query
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;