Reputation: 220
am stuck in a sql problem. I need something like this
M S C
1 sent 12
1 checked 15
1 rejected 9
2 sent 20
2 checked 18
3 rejected 10
Where M stands for Month, S for Status and C for Count respectively. What i want to achieve is to group the above example by Month
Wanted:
M S C
1 sent 12
checked 15
rejected 9
2 sent 20
checked 18
rejected 10
EDIT 1
Right now the sql statement looks like this:
select month, status, sum(hit) as count
from myTable
where dateletter between "date from" and "date to"
group by month,status order by month, status
Edit 2
How would i achieve this too
1 2
Sent 12 20
Checked 15 18
Rejected 9 10
where 1,2 represent the month values from database.
Upvotes: 1
Views: 144
Reputation: 79185
Using the BREAK ON
syntax of SQL*Plus :
> BREAK ON M
> SELECT 1 m , 'sent' s , 12 c FROM dual
2 UNION ALL SELECT 1 , 'checked' , 15 FROM dual
3 UNION ALL SELECT 1 , 'rejected' , 9 FROM dual
4 UNION ALL SELECT 2 , 'sent' , 20 FROM dual
5 UNION ALL SELECT 2 , 'checked' , 18 FROM dual
6 UNION ALL SELECT 3 , 'rejected' , 10 FROM dual
M S C
---------- -------- ----------
1 sent 12
checked 15
rejected 9
2 sent 20
checked 18
3 rejected 10
So, with your example:
SET LINESIZE 2000 TRIMSPOOL ON TRIM ON
BREAK ON MONTH
SPOOL file.txt
SELECT month, status, SUM(hit) AS count
FROM myTable
WHERE dateletter BETWEEN "date from" AND "date to"
GROUP BY month, status
ORDER BY month, status;
SPOOL OFF
Upvotes: 1
Reputation: 15473
Not exactly clear what you want from your example, but it sounds like you want to show the details for each month and status, but also want a group total for each month.
You can do this using a rollup analytic function in Oracle:
create table tst2
(
m number,
s varchar2(10),
hit number
);
insert into tst2 values (1,'sent',3);
insert into tst2 values (1,'checked',2);
insert into tst2 values (1,'rejected',4);
insert into tst2 values (2,'sent',6);
insert into tst2 values (2,'checked',1);
insert into tst2 values (2,'rejected',3);
commit;
select m,s,sum(hit) as cnt,
case
when (grouping(s) = 1 and grouping(m) = 1) then 'All total'
when (grouping(s) = 1 and grouping(m) = 0) then 'Month total'
else null
end as "Comment"
from tst2
group by rollup(m,s);
And you'll get
1 sent 3 1 checked 2 1 rejected 4 1 9 Month total 2 sent 6 2 checked 1 2 rejected 3 2 10 Month total 19 All total
See here for Oracle docs RE: analytic and reporting functions.
Upvotes: 1
Reputation: 112392
SELECT month AS M, status AS S, SUM(hit) AS C
FROM myTable
WHERE dateletter BETWEEN "date from" AND "date to"
GROUP BY month, status
ORDER BY month, status
In the query you cannot group further, you will have to do this in a report. The query is OK and can serve as record source for a report. In such a report, you would insert a group header for each month.
You could however make a pivot query
SELECT *
FROM
( SELECT month AS M, status AS S, SUM(hit) AS C
FROM myTable
WHERE dateletter BETWEEN "date from" AND "date to"
GROUP BY month, status
)
PIVOT (
SUM(C)
FOR S IN ('sent', 'checked', 'rejected')
);
This would return the status in columns
M sent checked rejected 1 12 15 9 2 20 18 10
Upvotes: 3