SQL Server – Adding Total Sum Below Column of Prices

aggregatesql serversql-server-2012

I am running this select query on my database:

Select Item.ItemId, Item.ItemDescription, Bid.BidPrice, bid.BidDate,
Sum(bid.bidPrice) over () as TotalBids
from Bid
inner join Item on bid.ItemId=Item.ItemId
where BidDate between '2016-08-24' and '2017-11-15'

I am getting the below result:

ItemId  ItemDescription BidPrice    BidDate     TotalBids
1       Frame           35         2016-08-24   3624
4       Wooden chair    40         2016-10-25   3624
2       Car             3000       2017-10-26   3624
3       Stand Fan       29         2017-10-30   3624
5       Black Sofa      400        2017-11-11   3624
6       Cabinet         120        2017-11-15   3624

My question is: Is it possible that instead of the Total Bids column with a total at each row I just get one total at the bottom of the BidPrice Column?

Best Answer

You can use a GROUP BY GROUPING SETS over the NULL set

SELECT itemid, itemdescription, biddate, totalbids, sum(bidprice)
FROM f
GROUP BY GROUPING SETS ( (itemid,itemdescription,biddate,totalbids), () );
 itemid | itemdescription |  biddate   | totalbids | sum  
--------+-----------------+------------+-----------+------
      1 | Frame           | 2016-08-24 |      3624 |   35
      2 | Car             | 2017-10-26 |      3624 | 3000
      3 | Stand Fan       | 2017-10-30 |      3624 |   29
      4 | Wooden chair    | 2016-10-25 |      3624 |   40
      5 | Black Sofa      | 2017-11-11 |      3624 |  400
      6 | Cabinet         | 2017-11-15 |      3624 |  120
        |                 |            |           | 3624
(7 rows)

Verified to work with PostgreSQL. SQL Server 2014 and SQL Server 2016.

CREATE TABLE f(
  itemid int,
  itemdescription varchar(255),
  bidprice int,
  biddate date,
  totalbids int
)
INSERT INTO f VALUES
    ( 1, 'Frame       ', 35  , '2016-08-24', 3624 ),
    ( 4, 'Wooden chair', 40  , '2016-10-25', 3624 ),
    ( 2, 'Car         ', 3000, '2017-10-26', 3624 ),
    ( 3, 'Stand Fan   ', 29  , '2017-10-30', 3624 ),
    ( 5, 'Black Sofa  ', 400 , '2017-11-11', 3624 ),
    ( 6, 'Cabinet     ', 120 , '2017-11-15', 3624 );

The docs at PostgreSQL are much better explaining this

Another method of doing this is with a UNION,

WITH t AS (SELECT * FROM f)
SELECT *
FROM f
UNION ALL
  SELECT null, null, (SELECT sum(bidprice) FROM f), null, null;

For your query, the first method would look like this..

SELECT Item.ItemId, Item.ItemDescription, Bid.BidPrice, bid.BidDate, sum(bidPrice)
FROM Bid
INNER JOIN Item ON bid.ItemId=Item.ItemId
WHERE BidDate between '2016-08-24' and '2017-11-15'
GROUP BY GROUPING SETS ( (Item.ItemId, Item.ItemDescription, Bid.BidPrice, bid.BidDate), () )