I am new to sql (using mysql) and I have the following problem. I need to create a table where first column is some months, and the next three are :
first column: total amount of previous months (from the one stated in 1st column)
second: total amount of current month
third: total amount of the following months.
Now I have done it in three seperate queries, and what I want to do next, is combine them somehow. I am totally new to sql, so my initial idea was to create three tables and inner join them, but I guess this is not neat approach. Is there any way I can do that properly?
I am attaching my 3 queries, plus my output:
# 1 column
select month(rdate),
(SELECT SUM(ramaount)
FROM my_table
WHERE (month(rdate) <(month(a.rdate)))
and year(rdate)=2015
) as total_previous
FROM my_table a
where year(rdate)=2015
group by month(rdate)
order by year(rdate),month(rdate);
# 2 column
select
month(rdate) as month_2015,
sum(ramaount)
from my_table
where year(rdate) in (2015)
group by month(rdate);
# 3h colum
SELECT month(rdate),
(SELECT SUM(ramaount)
FROM my_table
WHERE (month(rdate) >(month(a.rdate)))
and year(rdate)=2015
) as total_next
FROM my_table a
where year(rdate)=2015
group by month(rdate);
My three results currently are:
1,
3, 375
5, 1325
6, 3055
7, 4255
8, 10255
9, 10555
10, 10755
12, 10935
1, 375
3, 950
5, 1730
6, 1200
7, 6000
8, 300
9, 200
10, 180
12, 1200
1, 11760
3, 10810
5, 9080
6, 7880
7, 1880
8, 1580
9, 1380
10, 1200
12,
Best Answer
One alternative is to trade the correlated subqueries and, potentially, joins for using variables as well as a lot of nesting and sorting.
The starting point of the approach I am suggesting will be this query:
which is essentially your second query. According to your example, the output would be this:
The following query uses that as a derived table to calculate the running total from the first to the last month with the help of a variable:
In your case the returned rows would look like this:
Never mind that the
past_amount
value includes the current month whereas you seem to require otherwise – that will be rectified later.The next step would be to use the above as a derived table again and use the same method to calculate
future_amount
while sorting the rows in the opposite order:This would be the result:
Again, do not worry at this point about the
future_amount
results including the current month's amount.Your next, and last, step will be to nest the previous query one level more in order to sort the results back in the ascending order of months as well as to adjust
past_amount
andfuture_amount
aspast_amount - this_amount
andfuture_amount - this_amount
, respectively:And this is would you should get as the result:
I additionally used the NULLIF function on the subtractions to substitute NULLs for what otherwise would be 0s in the first row's
past_amount
and the last row'sfuture_amount
, because that was what your results seemed to suggest to me you wanted. If a 0 in both cases would do just fine, then do not use NULLIF.A demo of this approach is available at Rextester and SQL Fiddle.
We could also simplify by calculating the total first, so we don't have to do running sums, only one forward:
An extra logical table scan in the form of the total amount across the year has been added in exchange for extra sorts of the result set.
Both solutions at Rextester.