BlackCat
BlackCat

Reputation: 2044

How to show Sub Total value like this?

I have a table like this:-

Branch       SL       Month     Amount1 Amount2 Amount3
    A         1       January    100       0        0
    A         2       February     0       0        0
    A         3       March       80       0        0
    A         4       April        0      10       10
    A         5       May          0       0        0
    A         6       June         0       0        0
    A         7       July         0       0       10
    A         8       August       0      10        0
    A         9       September    0      10        0
    A        10       October     40       0       10
    A        11       November    10      10       10
    A        12       December     0      10       10
    B         1       January      0       0       10
    B         2       February    10      10       10
    B         3       March        0       0       10

Now, I am trying to show subtotal by every Branch, which will give output like this, where 'Subtotal' is shown after every 12 rows and right under the Month Column "Subtotal" is written. And the first 2 Column will be blank, I am trying to achieve this using UNION ALL but failed.

Branch  SL    Month   Amount1     Amount2    Amount3
A        1    January     100           0          0
A        2    February      0           0          0
A        3    March        80           0          0
A        4    April         0          10         10
A        5    May           0           0          0
A        6    June          0           0          0
A        7    July          0           0         10
A        8    August        0          10          0
A        9    September     0          10          0
A        10   October      40           0         10
A        11   November     10          10         10
A        12   December      0          10         10
              Subtotal    230          50         50
B        1    January       0           0         10
B        2    February     10          10         10
B        3    March         0           0         10

Upvotes: 0

Views: 78

Answers (2)

Ilyes
Ilyes

Reputation: 14928

Try this

CREATE TABLE T
(
   Branch VARCHAR(1),
   SL INT,
   Month VARCHAR(3),
   Amount1 INT,
   Amount2 INT,
   Amount3 INT
);

INSERT INTO T VALUES
('A', 1, 'Jan', 10, 0, 10),
('A', 2, 'Feb', 20, 0, 20),
('B', 1, 'Jan', 5, 5, 5),
('B', 2, 'Feb', 20, 0, 20),
('C', 1, 'Jan', 55, 44, 33);

WITH CTE AS
(
  SELECT *
  FROM T
  UNION ALL
  SELECT Branch + ' SubTotal', NULL, 'SubTotal', SUM(Amount1), SUM(Amount2), SUM(Amount3)
  FROM T
  GROUP BY Branch
)
SELECT Branch,
       SL,
       Month,
       Amount1,
       Amount2,
       Amount3
FROM CTE
ORDER BY Branch;

Results:

+------------+----+----------+---------+---------+---------+
|   Branch   | SL |  Month   | Amount1 | Amount2 | Amount3 |
+------------+----+----------+---------+---------+---------+
| A          |  1 | Jan      |      10 |       0 |      10 |
| A          |  2 | Feb      |      20 |       0 |      20 |
| A SubTotal |    | SubTotal |      30 |       0 |      30 |
| B          |  1 | Jan      |       5 |       5 |       5 |
| B          |  2 | Feb      |      20 |       0 |      20 |
| B SubTotal |    | SubTotal |      25 |       5 |      25 |
| C          |  1 | Jan      |      55 |      44 |      33 |
| C SubTotal |    | SubTotal |      55 |      44 |      33 |
+------------+----+----------+---------+---------+---------+

If you really need to get Branch and SL blank ('') you can do like

WITH CTE AS
(
  SELECT Seq = Branch + 'X1',*
  FROM T
  UNION ALL
  SELECT Branch + 'X2', '', NULL, 'SubTotal', SUM(Amount1), SUM(Amount2), SUM(Amount3)
  FROM T
  GROUP BY Branch
)
SELECT Branch,
       SL,
       Month,
       Amount1,
       Amount2,
       Amount3
FROM CTE
ORDER BY Seq;

and the results is the same as your expected results

+--------+----+----------+---------+---------+---------+
| Branch | SL |  Month   | Amount1 | Amount2 | Amount3 |
+--------+----+----------+---------+---------+---------+
| A      |  1 | Jan      |      10 |       0 |      10 |
| A      |  2 | Feb      |      20 |       0 |      20 |
|        |    | SubTotal |      30 |       0 |      30 |
| B      |  1 | Jan      |       5 |       5 |       5 |
| B      |  2 | Feb      |      20 |       0 |      20 |
|        |    | SubTotal |      25 |       5 |      25 |
| C      |  1 | Jan      |      55 |      44 |      33 |
|        |    | SubTotal |      55 |      44 |      33 |
+--------+----+----------+---------+---------+---------+

Upvotes: 0

Gordon Linoff
Gordon Linoff

Reputation: 1269693

One method uses grouping sets, but you need an aggregation query. You can write this as:

select Branch, SL, Month, sum(Amount1), sum(Amount2), sum(Amount3)
from t
group by grouping sets ( (Branch, SL, Month), (branch) );

grouping sets are only available from 2008 onwards. In earlier versions, you can do:

select t.*
from ((select branch, sl, month, amount1, amount2, amount3
       from t
      ) union all
      (select Branch, null, 'Subtotal', sum(Amount1), sum(Amount2), sum(Amount3)
       from t
       group by branch
      )
     ) t
order by branch,
         (case when sl is not null then 1 else 2 end),
         sl;

Upvotes: 2

Related Questions