Report Builder Multiple Group Matrix Calculation - sql-server

I have a Matrix created using Matrix Wizard in Report Builder 3.0(2014), having 2 row groups ,1 column groups and 2 values. After I create the matrix (included total and subtotal), I have a matrix that look just nice. But now I want to add one more cell for each columns groups (one row), to store the below value.
Value = Total of 1st row group + Total of 2nd row group - Total of 3rd row group ...
The matrix built just show me the subtotal of each row group which I don't need.
I want to ask how do I retrieve the result of total calculated by matrix itself and how do I identify them based on their row group value using expression? And also, how do I do this for every column groups which have different data?
I tried to look at the expression in design view of the matrix, it just shows [SUM(MyField)] for every cell in the Matrix (total & subtotal).
Or should I do it at another dataset using another query? If so, what query should I use and how do I put two dataset into one matrix?
My Matrix looks something like this :
Column Group
ROW GROUP 1 | ROW GROUP 2 | VALUE 1 | VALUE 2
Row Group 1 | Row Group 2 | [Sum(MyField)] | [Sum(MyField)]
| TOTAL OF ROW GROUP 1 | [Value] | [Value]
| ROW PLAN TO ADD | [Value(0)+Value | [Value(0)+Value
| (1)-Value(2)] | (1)-Value(2)]
CAPITALS : Column name, constant
[sqrbrkted] : Calculated Value
Normal : data inside table
I am new to Report Builder, sorry if I made any mistake. In case I didn't make myself clear, please do comment and let me know. Thank you in advance.
EDIT: I have figured out an approach to achieve my purpose at the answer section below. If anyone have other solution, please feel free to answer it. Thanks.

I solved this problem by changing my SQL query to make another dummy column which shows negative result if its respective row group is meant to deduct the subtotal (Value(2)), and place it inside the matrix. And inside the expression, I have another IIF statement to convert it back to positive for display purpose.
SQL:
SELECT *, (CASE WHEN COL_B = 'VAL_2' THEN -COL_A ELSE COL_A END)AS DMY_COL_A FROM TABLE
Expression:
=IIF(Sum(Fields!DMY_COL_A.Value)<0,-Sum(Fields!DMY_COL_A.Value),Sum(Fields!DMY_COL_A.Value))

Related

How to find the most frequently occurring value in SSRS tablix dataset?

Consider following dataset that is displayed in tablix in SSRS report:
GroupID | ProductID
---------------------
Group 1 | Product1
Group 2 | Product10
Group 1 | Product2
Group 3 | Product27
Group 2 | Product12
Group 2 | Product14
I added new row via Insert Row/Outside Group - Below.
On this row I display total number of rows - achieved via CountRows(), number of distinct Groups - achieved via =CountDistinct(Fields!GroupID.Value)
I also want to display the name of the group with the most number of rows, in this case it would be "Group 2" (in case if there is more than one group with the same number of rows I only need to display one of them).
How can this be achieved? I think I should use some of aggregate or lookup functions but so far can't figure out how.
PS This report is being ported from Crystal Reports to SSRS. In Crystal Reports this is easily achieved via "Nth most frequent" summary with N=1 but there is nothing like this in SSRS as far as I can tell.
Add a tablix and set GroupId as Row Group.
For Rows Count use:
=Count(Fields!GroupID.Value)
Right click GroupID group in the Row Groups pane and go to group properties, in the Filters tab use the following settings:
For Expression use:
=Count(Fields!GroupID.Value)
It will filter the top 1 group with the greatest Rows count. The result is something like this:
UPDATE: The previous solution doesn't work if there is more than one group with the same number of occurencies.
Add a tablix, delete the details (default group) and add the GroupID field in the first column.
For the Rows Count column use the following expression replacing DataSetName by the actual name of your dataset:
=LookupSet(
Fields!GroupID.Value,
Fields!GroupID.Value,
Fields!GroupID.Value,
"DataSetName"
).Length
Right click your tablix and go to tablix properties, in the Sorting tab select Z to A order and use the previous expression in the Sort By textbox.
It should show the only one group even if a second group with same number of occurencies is present.
Let me know if this helps.

SQLite delete rows based on multiple columns

im pretty new to SQLite hence asking this question!
I need to remove rows in a table so that I have the earliest occurence of column each unique value in column X(colour) based on column Y (time).
Basically i have this:
test | colour | time(s)
one | Yellow | 8
one | Red | 6
one | Yellow | 10
two | Red | 4
Which i want to remove rows so that is looks like:
test | colour | time(s)
one | Yellow | 8
two | Red | 4
Thanks in advance!
EDIT: To be clearer i need to retain the Earliest occurence in time that each colour occurred, regardless of the test.
EDIT: I can select the rows i want to keep by doing this:
select * from ( select * from COL_TABLE order by time desc) x group by colour;
which produces the desired result, but i want to remove what is not there in the result of the select.
EDIT: The following worked thanks to #JimmyB:
DELETE FROM COL_TABLE WHERE EXISTS ( SELECT * FROM COL_TABLE t2 WHERE COL_TABLE .colour = t2.colour AND COL_TABLE .test = t2.test AND COL_TABLE .time < t2.time )
You can include subqueries (EXISTS/NOT EXISTS) in the WHERE clause of a DELETE statement.
Like subqueries in SELECTs, these can refer to the table in the outer statement to create matches.
In your case, try this:
DELETE FROM my_table
WHERE EXISTS (
SELECT *
FROM my_table t2
WHERE my_table.colour = t2.colour
AND my_table.test = t2.test
AND my_table.time < t2.time
)
This statement uses three noteworthy constructs:
Subquery in DELETE
Self-join
Emulation of a MIN(...), via self-join
The subquery with EXISTS is mentioned above.
The self-join is required whenever one row of a table must be compared against other rows of the same table. Finding the minimum value of some column is exactly that.
Normally, you'd use the MIN(...) function to find the minimum. The minimum can be defined as the single value for which no lower value exists, and that's what we're using here because we're not actually interested in the actual value but only want to identify the record which contains that value.
(Since we're deleting, our SELECT yields all the non-minimum rows, which we want to delete to keep only the minimums.)
So, what the statement says is:
Delete all records from my_table for which there is at least one record in my_table with the same colour and the same test but a lower time.

Pivottable on SSAS cube: hide rows without result on measure

I'm having trouble hiding rows that have no data for certain dimension members for the selected measure, however there are rows for that member in the measuregroup.
Consider the following datasource for the measuregroup:
+---------+----------+----------+----------+--------+
| invoice | customer | subtotal | shipping | total |
+---------+----------+----------+----------+--------+
| 1 | a | 12.95 | 2.50 | 15.45 |
| 2 | a | 7.50 | | 7.50 |
| 3 | b | 125.00 | | 125.00 |
+---------+----------+----------+----------+--------+
When trying to create a pivottable based on a measuregroup in a SSAS-cube, this might result in the following:
However, I would like to hide the row for Customer b, since there are no results in the given pivottable. I have tried using Pivottable Options -> Display -> Show items with no data on rows but that only works for showing/hiding a Customer that's not at all referenced in the given measuregroup, say Customer c.
Is there any way to hide rows without results for the given measure, without creating a seperate measuregroup WHERE shipping IS NOT NULL?
I'm using SQL-server 2008 and Excel 2013
Edit:
For clarification, I'm using Excel to connect to the SSAS cube. The resulting pivottable (in Excel) looks like the given image.
In the DSV find the table with the shipping column and add a calculated column with expression:
Case when shipping <> 0 then shipping end
Please go to the properties window for the Shipping measure in the cube designer in BIDS and change the NullHandling property to Preserve. Change the source column to the new calculated column. Then redeploy and I am hopeful that row in your pivot will disappear.
And ensure Pivottable Options -> Display -> Show items with no data on rows is unchecked.
If that still doesn't do it connect the Object Explorer window of Management Studio to SSAS and tell us what version number it shows in the server node. Could be you aren't on the latest service pack and this is a bug.
Go in your pivot table in Excel, click on the dropdown on your customer column. In the dropdown menu you will find an option called Value Filters. There you can set something like Shipping greater than 0.1.
This filters your Customer dimension column based on the measure values.
Maybe something like this (but I don't see the pivot...)
DECLARE #tbl TABLE(invoice INT,customer VARCHAR(10),subtotal DECIMAL(8,2),shipping DECIMAL(8,2),total DECIMAL(8,2));
INSERT INTO #tbl VALUES
(1,'a',12.95,2.50,15.45)
,(2,'a',7.50,NULL,7.50)
,(3,'b',125.00,NULL,125.00);
SELECT customer, SUM(shipping) AS SumShipping
FROM #tbl
GROUP BY customer
HAVING SUM(shipping) IS NOT NULL

Filter Columns based the condition of a Row

I have the following Matrix in SSRS 2008 R2:
What I would like to do is only show columns where the "FTE" row has a value. (Marked with red circles). I've tried the filter and show/hide options based on expressions in the Column Properties, but I can't figure out how to only reference the rows when "category"="FTE". My data looks like this:
tblPhysicians
employee_id last_name ...
102341145 Smith
123252252 Jones
tblPhysiciansMetrics
id fy period division_name category_name employee_id
123 2014 1 Allergy Overhead 123456
124 2014 1 Allergy Salary 125223
125 2014 1 Allergy FTE 1.0
query
SELECT * FROM
tblPhysicians
INNER JOIN tblPhysicianMetrics
ON tblPhysicians.employee_id = tblPhysicianMetrics.employee_id
WHERE
tblPhysicianMetrics.division_name = #division_name
AND tblPhysicianMetrics.fy = #fy
AND tblPhysicianMetrics.period = #period
Notice that the rows in my Matrix is just the category_name, so I can't just hide when category_name = "FTE", that's not really what I want. What I really need is some way of saying, "For rows where category_name = "FTE", if the value is not set, don't show that column". Is this possible?
An alternative would be to not even get those in the query, but as with the filtering of the matrix, if I simply add "AND tblPhysiciansMetrix.category_name = 'FTE'" to the WHERE clause, my entire data set is reduced to only those records where category_name is FTE.
Any help is much appreciated!
Update: added definition of Matrix to help:
You need to set the column visibility with an expression that checks all underlying data in the column for the FTE category.
I have a simple dataset:
And a simple matrix based on this:
Which looks exactly as you expect:
So in the above example, we want the Brown column to be hidden. To do this, use an expression like this for the Column Visibility:
=IIf(Sum(IIf(Fields!category_name.Value = "FTE", 1, 0), "last_name") > 0
, False
, True)
This is effectively counting all the fields in the column (determined by the last_name scope parameter in the Sum expression) - if this is > 0 show the column. Works as required:
CAVEAT I'm not 100% sure how you are grouping this data in the matrix. It isn't 100% clear from your description. Let me know why this doesn't work (if it doesn't and I'll update my answer accordingly.
I've replaced the column employee_id with the name value for my answer, to keep my explanation simple.
Add this nested IIF() to the visibility property of your Matrix's column.
=IIF(Fields!category_Name.Value="FTE" ,IIF( Fields!value.Value >= 0, True,False),false)
It will check both the value of the the category and the 'FTE' in that row's cell.

ON COLUMNS compared to ON ROWS

Why in MDX is it ok to do the following:
SELECT
[MyDim].[MyHier].[MyLevel] ON COLUMNS
FROM [CubeName]
But not the following:
SELECT
[MyDim].[MyHier].[MyLevel] ON ROWS
FROM [CubeName]
I've never find any good reason for that ;-) on columns, on rows are defining the 'shape' of the result (the tuples being exactly the same) and it has been decided that on columns only is ok but not on rows only; i.e.:
a | b | c
1 | 2 | 3
but not:
a | 1
b | 2
c | 3
weird as I see no problem to return those values from an MDX server implementation point of view. By the way, no columns and no rows is valid :
select from [cube]
It seems that there is a hierarchy of axises. Columns is the first and minimal part in defining a Tuple:
When you specify an axis for a set (in this case composed of a single tuple) in a query, you must begin by specifying a set for the column axis before specifying a set for the row axis. The column axis can also be referred to as axis(0) or simply 0.
So you should first define Columns, then Rows, then Pages and so on.
<SELECT query axis clause> ::=
[ NON EMPTY ] Set_Expression
[ <SELECT dimension property list clause> ]
ON
Integer_Expression
| AXIS(Integer)
| COLUMNS
| ROWS
| PAGES
| SECTIONS
| CHAPTERS

Resources