SSRS - Subtracting column values without knowing row details - reporting-services

Got a question regarding SSRS. Using 2005 version.
I've got 2 tables in my report, one with the current months data and one with data for the last 3 months.
The last 3 months table always returns 3 rows, 1 row for each month. What I want to do is subtract a value from the 2nd oldest month, basically it will always be row 2 of the table with the equivalent column in the current months table. Hope this kind of makes sense.
I will use an example here;
Table 1
Month Value Var
August 5 ?
Table 2
Month Value
July 4
June 7
May 10
I want to use the Value in Table 1 and subtract the Value of the June column in Table 2 therefore 5 - 7, returning the value -2.
There is a month parameter so the Tables data would change depending on the month but it was always be the 2nd rows Value column that I want to use.
Is this possible in SSRS?
Thanks

Method 1:
It is better to solve this in the SQL (dataset) then in the report design.
If data comes from two different tables then
Select C.Month, C.Value, (C.Value - L.Value) AS Var
From CurrentMonthData C
Left JOIN (Select * Last3MonthData where Month = CurrentMonth - 2) L
ON 1=1
If data comes from same table
Select C.Month, C.Value, (C.Value - L.Value) AS Var
From (Select * MonthData Where Month = #CurrentMonth) C
Left JOIN (Select * MonthData where Month = #CurrentMonth - 2) L
ON 1=1
Method 2:
If you prefer to do it in the Report Itself you can use ReportItems collection.
In the variance text box value put
=ReportItems!CurrentMonthValueTextBox.Value - ReportItems!Prev2MonthValueTextBox.Value
HTH.

you may try using LookupSet or MultilookupSet

Related

Get value difference between two dates in MySQL

I have a following table structure:
page_id view_count date
1 30 2018-08-30
1 33 2018-08-31
1 1 2018-09-01
1 5 2018-09-02
...
View count is reset on 1st of every month, and it's current value is stored on a daily basis, so on 31st of August it was increased by 3 (because 33-30).
What I need to do is to retrieve the view count (difference) between two dates through SQL query. To retrieve view count between two dates in same month would be simple, by just subtracting bigger date with the lower date, but retrieving between two dates that are in different months is what's not sure to me how to achieve. If I wanted to retrieve data between 2018-08-13 and 2018-09-13 I would have to get difference between 2018-08-31 and 2018-08-13, and add it to the value of 2018-09-13.
Also, I would like to do it for all page_id at once, between the same dates if possible within a single query.
assuming that the counter is unique per page and that the page_id counter is inserted daily into the table, I think that such a solution would work
The dates are based on the example,
and should be replaced by the relevant parameters
SELECT
v1.view_count + eom.view_count - v2.view_count
FROM
view_counts v1
INNER JOIN view_counts v2 ON v2.page_id = v1.page_id AND v2.`date` = '2018-08-13'
INNER JOIN view_counts eom ON v2.page_id = v.page_id AND eom.`date` = LAST_DAY(DATE_ADD(v.`date`, INTERVAL -1 MONTH))
WHERE
`date` = '2018-09-13'

Finding difference at group level

I have 3 months of AR data. From SQL I am populating details records for 3 months. In SSRS I am grouping the totals by month and showing only group summary. I want to calculate the variance by difference between current month and previous month. Please see the attached output file.
Could anyone help me on finding the variance at group level. How do I calculate the difference by using previous function?
Is there any way to find individual group sum of the particular field like this one
Sum(Fields!Current.Value, "DataSet1")
Something like this perhaps?
=Sum(iif(month(Fields!myDate.Value) = month(Max(Fields!myDate.Value)), Fields!myVal.Value, 0))
-Sum(iif(month(Fields!myDate.Value) = month(dateadd("M", -1, max(Fields!myDate.Value))), Fields!myVal.Value, 0))
Where myDate is the date used to group the months on, and myVal is the specific data for the column
UPDATE
Using this dataset
EOM myValue
09/30/2015 2
10/31/2015 6
11/30/2015 19
Gives this basic report
You can then use this formula (based on the original one in the original answer above) to determine the difference between the last and the penultimate row
=Sum(
iif(month(CDate(Fields!EOM.Value)) = month(Max(Fields!EOM.Value)),
Fields!myValue.Value,
0)
)
-Sum(iif(month(CDate(Fields!EOM.Value)) = month(dateadd("M", -1, max(CDate(Fields!EOM.Value)))),
Fields!myValue.Value,
0)
)
Then place this in the footer of the tablix as shown
This shows the difference between the two rows
Is this the behaviour you require? If not please clarify further in the original question as an update/edit.

dynamic query for multiple items from a single record from one table

I have a table (arealist) which has an ID field and multiple fields for tracking membership by year (M2012, M2013, etc) where each year's value is Yes or No. I can build a query to extract the fields I want (SELECT M2011, M2012, M2013, M2014 FROM arealist WHERE ID = 675;) but the fields will be growing in the future years adding M2015, M2016, M2017, etc.
HOW can I build a dynamic query that extracts the current Year info plus 4 years back.
Example: EndYear = 2014 - need 4 years back so answer will be M2011, M2012, M2013, M2014).
SELECT ??? FROM arealist WHERE ??? RANGE (BegYear to EndYear) AND ID = 675;
You should make the year a proper field, changing 1 row with columns M2011, M2012, M2013, M2014,ID to 4 rows with columns M, YEAR, ID (YEAR takes integer values from 2011 to 2014).
Next year, you add one row for each ID with YEAR=2015, and so on, without changing the table definition or your code:
SELECT M from AREALIST where ID= ? AND YEAR >= ? AND YEAR <= ?

Get sum of values based on the value of 2 other date related columns

Given the sample data in the screenshot below, would it be possible in mysql to return a sum of values from monthly_amount only where the values are before this month. I used a join to pull this data. The 5 left columns are from one table, and the rest are from another.
The issue I'm running into is, lets say its April of 2015, I can't just do a sum WHERE goal_year <= 2015 AND month_id_FK <= 4, or else I'll get only those 4 months from both years, when in that scenario, I really want all the months from 2014, plus the 4 months from 2015.
I could handle this in PHP, but I wanted to first see if there would be a way to do this in mysql?
try
WHERE Goal_Year*100+month_id_FK <= 201504
alternatively:
WHERE
GOAL_YEAR < 2015 OR
(GOAL_YEAR = 2015 and month_id_FK <= 4)
select sum(monthly_amount) from table where goaldate<(SELECT CURDATE())
this is not the actual query for your table..but if you do like this you will get the answer
you need the sum of monthly amount where the date is before current-date means today.
then you can just compare the currentdate with goal date

Get stats for each day in a month without ignoring days with no data

I want to get stats for each day in a given month. However, if a day has no rows in the table, it doesn't show up in the results. How can I include days with no data, and show all days until the current date?
This is the query I have now:
SELECT DATE_FORMAT(FROM_UNIXTIME(timestamp), '%d'), COUNT(*)
FROM data
WHERE EXTRACT(MONTH FROM FROM_UNIXTIME(timestamp)) = 6
GROUP BY EXTRACT(DAY FROM FROM_UNIXTIME(timestamp))
So if I have
Row 1 | 01-06
Row 2 | 02-06
Row 3 | 03-06
Row 4 | 05-06
Row 5 | 05-06
(i changed timestamp values to a day/month date just to explain)
It should output
01 | 1
02 | 1
03 | 1
04 | 0
05 | 2
06 | 0
...Instead of ignoring day 4 and today (day 6).
You will need a calendar table to do something in the form
SELECT `date`, count(*)
FROM Input_Calendar c
LEFT JOIN Data d on c.date=d.date
GROUP BY `date`
I keep a full copy of a calendar table in my database and used a WHILE loop to fill it but you can populate one on the fly for use based on the different solutions out there like http://crazycoders.net/2012/03/using-a-calendar-table-in-mysql/
In MySQL, you can use MySQL variables (act like in-line programming values). You set and can manipulate as needed.
select
dayofmonth( DynamicCalendar.CalendarDay ) as `Day`,
count(*) as Entries
from
( select
#startDate := date_add( #startDate, interval 1 day ) CalendarDay
from
( select #startDate := '2013-05-31' ) sqlvars,
AnyTableThatHasAsManyDaysYouExpectToReport
limit
6 ) DynamicCalendar
LEFT JOIN Input_Calendar c
on DynamicCalendar.CalendarDay = date( from_unixtime( c.date ))
group by
DynamicCalendar.CalendarDay
In the above sample, the inner query can join against as the name implies "Any Table" in your database that has at least X number of records you are trying to generate for... in this case, you are dealing with only the current month of June and only need 6 records worth... But if you wanted to do an entire year, just make sure the "Any Table" has 365 records(or more).
The inner query will start by setting the "#startDate" to the day BEFORE June 1st (May 31). Then, by just having the other table, will result in every record joined to this variable (creates a simulated for/next loop) via a limit of 6 records (days you are generating the report for). So now, as the records are being queried, the Start Date keeps adding 1 day... first record results in June 1st, next record June 2nd, etc.
So now, you have a simulated calendar with 6 records dated from June 1 to June 6. Take that and join to your "data" table and you are already qualifying your dates via the join and get only those dates of activity. I'm joining on the DATE() of the from unix time since you care about anything that happend on June 1, and June 1 # 12:00:00AM is different than June 1 # 8:45am, so matching on the date only portion, they should remain in proper grouping.
You could expand this answer by changing the inner '2013-05-31' to some MySQL Date function to get the last day of the prior month, and the limit based on whatever day in the current month you are doing so these are not hard-coded.
Create a Time dimension. This is a standard OLAP reporting trick. You don't need a cube in order to do OLAP tricks, though. Simply find a script on the internet to generate a Calendar table and join to that table.
Also, I think your query is missing a WHERE clause.
Other useful tricks include creating a "Tally" table that is a list of numbers from 1 to N where N is usually the max of the bigint on your database management system.
No code provided here, as I am not a MySQL guru.
Pseudo-code is:
Select * from Data left join TimeDimension on data.date = timedimension.date