SSRS Calculating Totals - reporting-services

In SSRS I have a report generated from a stored procedure. I have one column that is named "Price" and the report has various groupings (shown below). So because there are so many groupings there are a lot of totals for price. I need to roll these totals up into the parent grouping of TimeRange as an average. This is so I can know the average price of Z product was X. I obviously know that this is done by adding up all those totals and dividing by the amount of totals but I don't know how this can be done in SSRS. Is it possible to dynamically add up all those totals? Or maybe set some kind of global variables to handle this?
EDIT: I described the problem a bit wrong. It seems the main problem is the fact that the price data returns all positive "prices" then the report uses the other columns to define if the price is negative or not(if we bought something or sold something). Since I didn't think there was a way to compensate this through the microsoft code. I Grouped them together based on the rules and multiplied the prices that should be negative by -1. I Now want to figure out a way to take these individual totals and combine them into one Subtotal. It would do this by taking a Sum of the totals. Just doing a straight Sum(Price) doesn't help because that will just get all of the values directly from the query before the report touches them and those values are all positive which throws off the report data.
So i guess there are three solutions here:
1.There is some magical SSRS code that allows me add together data that is outputted from an expression instead of the initial database value and does that dynamically..
2.There is some kind of way to define and assign global variables in the report then I could use some kind of psuedo code to add and subtract data from the variable and then take the average of the total
3.This is currently not possible and I will have to completely rewrite the source data's process or come up with another solution that's not SSRS.
TimeRange
_
| Product
| _
| |
| | Time Unit
| | _
| | |
| | | TransactionType
| | | _
| | | |
| | | | Pay Status
| | | | Price Total Calculated Here [Sum(Price)]
| | | |_
| | |
| | |_
| |
| |_
|
|
|
|_

Reporting Services makes this very easy - in fact, if you were to just use the wizard (table wizard in Report Builder, report wizard in Visual Studio/BIDS), and add all of your grouping fields to the "groups" section, and then enable subtotals, the summing would be done for you, and you could then alter the field using an expression to divide the two summed fields.
Here's a link to some more useful information on grouping and aggregates:
http://technet.microsoft.com/en-us/library/ms170712.aspx

Use the Avg function to get an average of all the values in your grouping:
=Avg(Fields!Price.Value)

Related

SSRS Report - Horizontally Sort Columns Across Column Groups

I am creating an unusual SSRS report that requires that the user be able to use parameters to select which of the (more than 250) fields appear in the report. So the number of columns in this report can vary greatly.
I've been mostly successful at implementing this, but am stuck at controlling how to change the order of the columns.
Here is (a simplified example) of my original data:
My data as a screen capture
CompanyID | Address | Website_URL | Date_Created | Date Modified |
1 |123 Main Street|www.fake.com | 3/14/2019 | 3/15/2019 |
2 |555 Park Ave |www.notreal.com|3/12/2019 | 3/13/2019 |
The first thing I've done is to unpivot my data within my dataset (i used cross apply to do this). The name of what the column used to be is kept in a column named something like "Col_1", and the value is kept in a column named something like "Val_1". The trick is, I have to do this multiple times, once for each data type that I'm dealing with. Because obviously you can't have dates and nvarchars in the same column. When I unpivot the data above, it looks like this:
CompanyID | Col_1 | Val_1 | Col_2 | Val_2 |
1 |Address |123 Main Street | Date_Created | 3/14/2019 |
1 |Website_URL |www.fake.com |Date Modified | 3/15/2019 |
2 |Address |555 Park Ave |Date_Created |3/12/2019 |
2 |Website_URL |www.notreal.com |Date Modified |3/13/2019 |
The point in doing this is now I can create a matrix is the SSRS report with the CompanyID as a row group. Then I create two adjacent column groups for Col_1, and Col_2, which have as their values Val_1 and Val_2, respectively.
Click here to see SSRS Groupings
Now, when this report runs, each column group (for example, Col_1) expands out to show all the column names I had under that column in my unpivoted data. This could be dozens of columns. This picture shows what my final data looks like. This is similar to what my original data looked like. But with the benefit of the fact that the columns are being displayed dynamically.
My resulting Matrix
So, the only problem I'm having is that the columns are stuck within their groups. Say I want to sort them alphabetically, I can only sort the nvarchars together, and the dates together. I cannot sort the across their groups. Is there a way I can do this?
The resulting Matrix I want, with columns sorted alphabetically
Thanks in advance for any ideas.
Using your original unpivoted data, the design of your report needs to have 4 column groups.
1.Address
2.Date created
3.Date modified
4.Website URL

Periodic snapshot fact table - Possibly missing some captures

I am tracking employee changes daily in a DimPerson dimension table, and filling up my fact table each end-of-month and counting Hires, Exits, and Headcount.
For this example, let's say I will be populating the fact table end-of-month April 30th. Now here's the problem I am facing:
I have an employee record on April 17th that's a "Hire" action, so at that point in time my DimPerson table reads like this:
+-------+-----------+----------+--------+--------------------+-------+
| EmpNo | Firstname | LastName | Action | EffectiveStartDate | isCur |
+-------+-----------+----------+--------+--------------------+-------+
| 4590 | John | Smith | Hire | 4/17/2017 | Y |
+-------+-----------+----------+--------+--------------------+-------+
Now 2 days later, I see the same employee but with an action "Manager Change", so now my DimPerson table becomes this:
+-------+-----------+----------+-----------------+--------------------+-------+
| EmpNo | Firstname | LastName | Action | EffectiveStartDate | isCur |
+-------+-----------+----------+-----------------+--------------------+-------+
| 4590 | John | Smith | Hire | 4/17/2017 | N |
| 4590 | John | Smith | Manager Change | 4/19/2017 | Y |
+-------+-----------+----------+-----------------+--------------------+-------+
So at Month end, when I select all "Current" employees, I will miss the Hire capture for this person since his most recent record is just a manager change and the actual hiring happened "in-month".
Is this normal that you can miss certain changes when doing a periodic snapshot? What you recommend I do to capture the Hire action in this case?
Sounds like you need to fill up your fact table differently- you need a reliable source of numbers of hires, exits and headcount. You could pick those events up directly from the source system if available, or pick them up from your dimension table (if it was guaranteed to contain all the history, and not just end-of-day changes).
The source system would be the best solution, but if the dimension table overall shows the history you need, then rather than selecting the isCur people and seeing their most recent action, you need to get all the dimension table records for the period you are snapshotting, and count the actions of each type.
However I would not recommend you use the dimension table at all to capture transactional history. SCDs on a dimension should be used to track changes to the dimension attributes themselves, not to track the history of actions on the person. Ideally, you would create a transactional fact table to record these actions. That way, you have a transactional fact that records all actions, and you can use that fact table to populate your periodic snapshot at the end of each month, and your dimension table doesn't need to worry about it. Think of your dimension table as a record of the person, not of the actions on the person.
If your fact is intended to show the organizational change at the month end, I would say it is working as designed. The employee has a manager at the end of the month, but did not exist at the end of the previous month. This implies the employee was hired during the month. With a monthly grain, it should not be expected to show the daily activity.
Our employee dimension contains the hire date as a Type 1 attribute. We also include hire date in certain fact tables to allow a role playing relationship with the date dimension.

Better database basis for table with multiple date informations

What do you think is the better basis, in sense of "easyer to use" with SQL Syntax - the first or the second table?
Please give reasons.
table one:
+----+--------------------------------------+
| id | date1 | date2 | date3 |
+----+------------+------------+------------+
| 1 | 2014-02-15 | 2014-03-24 | 2014-03-24 |
| 2 | NULL | NULL | 2014-08-15 |
| 3 | 2014-06-13 | NULL | NULL |
| 4 | 2014-01-10 | 2014-09-14 | 2014-01-12 |
+----+------------+------------+------------+
table two:
+----+------------+-------+-------+-------+
| id | date | one | two | three |
+----+------------+-------+-------+-------+
| 1 | 2015-07-04 | true | true | false |
| 2 | 2014-06-13 | false | true | false |
| 3 | 2014-11-11 | true | false | false |
| 4 | 2017-03-02 | false | true | true |
+----+------------+-------+-------+-------+
(content of tables doesn't match in this example)
I just want to know if it is easier to deal with when you have just one date field and additional boolean fields instead of multiple date fields. For example if you want to have SELECTs like this
That depends what the dates are.
Just because two fields are both dates tell us nothing about what they have to do with each other, if anything.
If the three dates are totally unrelated and would never be interchangeable in processing, and if they are a fixed set that is not likely to change frequently, like "birth date", "hire date", and "next annual review date", then I would just make them three separate fields. Then when you write queries it would be very straightforward, like
select employee_id, name from employee where next_annual_review_date='2015-02-01'
On the other hand, if you might quite reasonably write a query that would search all three dates, then it makes sense to break the dates out into another table, with a field that identifies the specific date. Like I created a table once for a warehouse system where there were many dates associated with a stock item -- the date it arrived in the warehouse, the date it was sold, inventoried, returned to the warehouse (because the customer returned it, for example), re-sold, lost, damaged, repaired, etc. These dates could come in many possible orders, and many of them could occur multiple times. Like an item might be damaged, repaired, and then damaged and repaired again, or it could be sold, returned, sold again, and returned again, etc. So I created a table for the stock item with the "static" info like part number, description, and the bazillion codes that the user needed to describe the item, and then a separate "stock event" table with the stock item id, event code, the date, and various other stuff. Then there was another stock event table that listed the event codes with descriptions.
This made it easy to construct queries like, "List everything that has happened to this item in the past four years in date order", or "list all items added to the inventory in November", etc.
Your second table seems like an all-around bad idea. I can't think of any advantage to having 3 Boolean fields rather than one field that says what it is. Suppose the three dates are birth date, hire date, and next review date. You could create codes for these -- maybe 1,2, 3; maybe B, H, R; whatever. Then selecting on a specific event is easy enough either way, I guess: select date where hire = true versus select date where event = 'H'.
But listing multiple dates with a description is much easier with a code. You just need a table of codes and descriptions, and then you write
select employee_name, event_code, date
from employee e
join employee_event ev on ev.employee_id=e.employee_id
join event v on v.event_id=ev.event_id
where ... whatever ...
But with the Booleans, you'd need a three-way case/when.
What happens when new event types are added? With an event code, it's just a data change: add a enw record to the event code table. With the Booleans, you need to change the database.
You create the potential for ambiguous data. What happens if two of the Booleans are true, or if none of them are true? What does that mean? There's a whole category of error that can't possibly happen with event codes.
Neither of those are normalized. Normalization is a good way to avoid data anomalies and keep things DRY.
What do your dates represent? What does "one", "two", and "three" represent?
I would go with something like this:
create table my_table (
my_table_id int primary key,
a_more_descriptive_word_than_date date not null,
label text not null
);
The data would look like this:
id date label
1 2014-12-23 one
2 2014-12-24 two
3 2014-12-25 three

#Error field in query

I am calculating Taxes being taken out of a check, and the net payment.
There are 4 tax percentages that are entered on a form, and I am using those to multiply against the Gross amount (either Payout, or Award). When I try to use the tax amounts alone, I receive #Error in the field when the query is ran.
The formulas are as follows:
FICATax: Format(IIf([MCR_EarningsCode]='LTF',
[MCR_AwardGross]*[Forms]![AstProfileFrm]![FicaTaxTxt],
[MCR_PytAmt]*[Forms]![AstProfileFrm]![FicaTaxTxt]),"Currency")
LocalTax: Format(IIf([MCR_EarningsCode]='LTF',
[MCR_AwardGross]*[Forms]![AstProfileFrm]![LocalTaxTxt],
[MCR_PytAmt]*[Forms]![AstProfileFrm]![LocalTaxTxt]),"Currency")
Now, when I try to use these 2 fields in my Net payment calculation, I receive #Error.
Net Payout formula:
NetPayment: Format(Round(IIf([MCR_EarningsCode]='LTF',
[FICATax]+[LocalTax], <-- Error
[MCR_PytAmt]-[FederalTax]-[StateTax]-[FICATax]-[LocalTax]),2),"Currency") <-- This works
Sample data:
+---------------+--------------+------------+------------+----------+---------+----------+
| MCR_AwardGross| EarningsCode | MCR_PytAmt | FederalTax | StateTax | FICATax | LocalTax |
+---------------+--------------+------------+------------+----------+---------+----------+
|#1) $34,000 | LTF | | | | $340.00 | $340.00 |
+---------------+--------------+------------+------------+----------+---------+----------+
|#2) | LTR | $11,500.00 | $2,875.01 | $402.50 | $115.00 | $115.00 |
+---------------+--------------+------------+------------+----------+---------+----------+
|#3) | LTR | $8,341.60 | $2,085.40 | $291.96 | $83.42 | $83.42 |
+---------------+--------------+------------+------------+----------+---------+----------+
The results for Net Payment would be:
#Error => [FICATax]+[LocalTax]
$2,992.55 => [MCR_PytAmt]-[FederalTax]-[StateTax]-[FICATax]-[LocalTax]
$5,797.40 => [MCR_PytAmt]-[FederalTax]-[StateTax]-[FICATax]-[LocalTax]
Personally, I don't see how it could be an issue with Null values, because there will never be a Null value in any of the calculations. Is there an issue with dealing with these fields at run time?
Note: I got it to work by adding a 0 in front of the calculation.
0-[FICATax]-[LocalTax] .. However, I am curious why it won't add the two 'fields?'
I suspect the problem stems from the fact that the Format() function converts a number to a string. In some cases Access will automatically convert strings back to numbers if we try to perform math with them. However, in your more complicated cases that appears to fail. Adding the '0-' prefix acts as a hint that the result should be numeric.
Another possible fix would be to explicitly convert the strings (as produced by Format()) back into currency values with CCur(). However, you may also reconsider whether you really want to format those values, especially if they will be used in subsequent calculations. I always recommend keeping numbers as numbers (and dates as dates) in queries. If you need special formatting you can always apply it at the presentation level, e.g., in the .Format property of a Text Box control on a Report.

Displaying a Crosstab Query with Variable Fields in a Subform

Microsoft Access 2010 here. Working with reports (and forms).
I have a crosstab query that transforms (w/ UNION ALL, thank you Bluefeet!) and pivots another "source query" with the purpose of making the results more coherent to the reader. The source query has fields that do not change, but rows that do, as the source query only selects results from the past 30 days; the fields of the subsequent crosstab query are not expected to stay the same upon requery as the rows have become the fields and vice-versa. What I am wondering is how one would display such a crosstab query in a subform as-is; i.e. as a simple reference with no record-dependence.
An example of the variable fields in the crosstab query:
Criteria | 11/26/2012 | 11/27/2012 | 11/29/2012 | 12/6/2012 ...
# Insp | 7 | 8 | 8 | 9
# Passed | 5 | 4 | 5 | 7
# Failed | 2 | 4 | 3 | 2
% Acceptance | 71% | 50% | 63% | 78%
I have successfully tied the crosstab query to a subform "child" for display through it's "Source Object" property, and achieved the desired end-result, but there was the record selection bar which is undesired for a reference, and the option to display it, normally found on forms/subforms is gone on the subform "child."
This leaves me wondering if there is another way to do display crosstab queries in subforms, or if I am looking in the total wrong direction to achieve the task. The report includes a graph based on the source query and below that is to be the crosstab query, displayed purely for reference. Thank you for the help!