How to not COUNT a value in SSRS matrix when value is NULL - reporting-services

I cannot make the my expression NOT count a NULL value in my SSRS matrix.
In my SSRS matrix, I have 2 columns one for AppraisalCompany and a count under the SubmittedDate column. In my report this what is happening:
Per Derrick's suggestion here is the change I made in the ColumnGroup properties for the SubmittedDate:
Here is my expression change in the ColumnGroup properties:
Unfortunately I got this error:

I'm suspicious of your Dataset, I'm not entirely sure how you're getting a null value to return 1 in the COUNT. I have been unable to reproduce your results.
Dataset Query
SELECT 'Drive In' AS AppraisalCompany, NULL AS SubmittedDate
UNION
SELECT 'Photo App - English', 'Dec-18'
Next I created a Row Group on AppraisalCompany and a Column Group on SubmittedDate.
I filtered the column group to remove the null grouping, using the expression =IsNothing(Fields!SubmittedDate.Value), operator <>, and Value true.
In the textbox in the matrix I used [Count(SubmittedDate)].
OUTUT
Appraisal Company | Dec-18
-------------------------------
Drive In | 0
Photo App - English | 1

By a Decimal (Number) datatype Nothing and 0 are the same. You can test this.
Put a tablix into your report with year from 2017 to 2019. Then put the year in a column of the tablix as a number format, then write the following expression in the detail textbox:
=CDec(IIF(CDec(Fields!Year.Value) = 2017, 0, Nothing))
After executing your report you will notice that every value in the year column is 0.
The same goes for the check. Both of these expressions will always return Yes. I basically check for 0 and the second one for for Nothing:
=IIF(CDec(IIF(CDec(Fields!Jahr.Value) = 2017, 0, Nothing)) = 0, "Yes", "No")
=IIF(CDec(IIF(CDec(Fields!Jahr.Value) = 2017, 0, Nothing)) = Nothing, "Yes", "No")
But remember your textbox/column has the be a number format.
So if you want to return Nothing and you display it in a number format textbox, it will show you a 0.
With this in mind it will make sense that a Count() returns the value 1 for 0 AND Nothing. So basically this will do the trick:
'Cont
=Sum(IIF(Fields!YourValue.Value = Nothing, 0, 1))

Related

Using like operator in SSRS Expression

I have a tablix with following results.
SSRS Result
Since i am learning SSRS. i wonder how to Sum line total with respect to product name. Since product name has duplicate values but it has only M and Xl difference. If i use row group it won't total like i expected since it has M and Xl difference. I wonder how to write an expression for the total.
The desired result set
May 31 2011 S043659 Long-Sleeve Logo jerse M 3 $86.52
Long-Sleeve Logo jersey XL 1 $28.84
Total $115.36
mountain bike socks M 6 $34.20
i used this expression but giving me an error.
`IIF((Fields!Product.value = Previous(Fields!Product.value),Sum(Fields!linetotal.value))`
There's actually a few things wrong with your expression.
The IIF doesn't have a 3rd argument for the ELSE value. In this case, you'd want to use 0. So the expression would be IIF the fields match then LineTotal Else 0.
You want to have the SUM on the outside of the IIF, otherwise it will only SUM one row.
The matching without the size is trickier. I have it trim off the last 4 characters to exclude the size for a match - it may not work depending on your other Product names.
=SUM(IIF(LEFT(Fields!Product.value, LEN(Fields!Product.value) - 4) = LEFT(Previous(Fields!Product.value), LEN(Fields!Product.value) - 4), Fields!linetotal.value, 0))
The expression reads the SUM of (IF the Product matches the Previous Product then the Line Total else 0).
All this being said, it would actually be easy to crate a parent group and GROUP BY on the parent product. Unfortunately, your data uses a comma to separate one type (jersey) by size but a space in another (socks) so I don't see how to do it. If they all had a comma, I would create a Calculated Field on the dataset to use the product-line up to the comma.
=LEFT(Fields!Product.value, INSTR(Fields!Product.value, ",") - 1)
IF your Product line is either a comma or space to separate, you might be able to use this for your Calculated Field:
=LEFT(Fields!Product.value,
IIF(INSTR(Fields!Product.value, ",") > 0,
INSTR(Fields!Product.value, ",") - 1,
InStrRev(Fields!Product.value, " ") - 1) )

SSRS: How to add an condition in the expression while counting rows?

I need help with writing a conditional expression for counting specific rows of the dataset using which I determine to make a textbox visbile
DataSet_Example
Name value Level
ABC 12345 PG1
DEF 45677 PG2
FEG 98098 PG1
I want to count the rows based on the level. Something Like the one below
iff(CountRows("DataSet_Example").Level == PG1 < 1)
How do I do it in SSRS expressions?
You need insert a row group for "Level" and then set your visibility expression for each row to the following:
=IIF(CountRows("Level") > 1 , condition if true, condition if false )

having trouble understanding CASE WHEN statement in SQL

SELECT state,
COUNT(CASE WHEN elevation >= 2000 THEN 1 ELSE NULL END) as count_high_elevation_aiports
FROM airports
GROUP BY state;
In the above statement, what is the THEN 1 and what does '1' signify?
How does that value '1' after THEN affect the output?
First, note that these three expressions are equivent:
CASE WHEN elevation >= 2000 THEN 1 ELSE NULL END
IF(elevation >= 2000, 1, NULL)
((elevation >= 2000) OR NULL)
If elevation >= 2000, the expression evaluates as "1", otherwise the expression evaluates as NULL.
"1" is conventionally used as boolean true, and you could substitute the MySQL literal TRUE in the above expressions with equivalent results... but that isn't what the "1" is for, here.
When used with COUNT(), in cases like this, the only real significance of 1 is that it is not NULL.
This is important, because -- contrary to popular belief -- COUNT() does not count rows. It counts values.
What's the difference? NULL is not technically a value. Instead, it is a marker that signifies the absence of a value, thus COUNT(expr) only counts rows where expr is not null.
By using an expression like the one here, you're asking the server to count the rows with elevation => 2000, and you do this by giving COUNT() a NULL for rows you want not to be counted... and a non-null value for rows you do.
Aggregate (GROUP BY) functions operate on values -- and NULL, again, is not a value in this sense.
Another aggregate function that makes this rationale perhaps even more clear is AVG(). If you had 3 rows... with values 5, NULL, and 10... what's the average? If you said 7.5, that's correct: the average of these 3 rows is (5 + 10) ÷ 2 = 5 because the 3 rows have only two values. NULL is not 0, otherwise the average would be (5 + 0 + 10) ÷ 3 = 5, which it is not.
So, that's how and why this works.
How does that value '1' after THEN affect the output?
It really doesn't. You could just as easily have said COUNT(CASE WHEN elevation >= 2000 THEN 'cat videos are funny' ELSE NULL END) because, just like the literal 1, the literal string 'cat videos are funny' is also not null, and non-null values -- anything not null -- is what count will count.
A novice might try to accomplish this task with COUNT(elevation >= 2000), but that gives the wrong answer, because the 0 (false) for rows where elevation is < 2000 is not null, so these rows would still be counted.
You may then ask, "why not just use COUNT(*) ... WHERE elevation >= 2000?" Good question. The reasons vary, but if you GROUP BY state and there are states with no rows matching WHERE, those states would be entirely eliminated from the results, which is often not what you want. This query includes them, with a count of zero.
Note that ((elevation >= 2000) OR NULL), the third example expression at the top, doesn't actually need the parentheses. I included them because this form is not necessarilly intuitive at first glance. The natural precedence of operations will cause this to be evaluated correctly if written simply elevation >= 2000 OR NULL. This expression is equivalent to the other two because elevation >= 2000 first evaluates to 1 if true, 0 if false, or NULL if elevation is null. Then the lower-precedence OR is evaluated, and you get one of these: 1 OR NULL => 1 ... 0 OR NULL => NULL ... NULL OR NULL => NULL... and you may actually be awarded a SQL wizard badge by the elders of the Internet at the point when writing queries with COUNT(elevation >= 2000 OR NULL) comes naturally to you.
Query will simply return 1 if elevation is > or = 2000, else it will return NULL (this is use full for boolean representation of field because NULL represents 0),
Now returned value will be set into count_high_elevation_airports.

SSRS 2012 using switch statement with LookupSet count in group footer

Apologies for the long post.
I have an SSRS 2012 report looking at 2 datasets, Dataset1 and Dataset2.
Dataset2 may return 0, 1 or 2 records, so I'm using LookupSet to do this. From the records returned, I need to display several fields.
The report is grouped by Main_ID. In the footer of Main_ID, I am counting the number of returned records from Dataset2.
=LookupSet(Fields!MainID.Value, Fields!MainID.Value, Fields!Record_Name.Value, "Dataset2").Length
This works fine, I'm getting 0, 1 or 2 as appropriate.
In Dataset2 the field:
HasIP
will be used to determine which record in the array I display (as I need to test a field value in Dataset2).
I'm trying to use a switch statement to use the length of the LookupSet array to return the correct fields.
If there are no records (eg length of array = 0) then return the
number 2
If there is 1 record (eg length of array = 1), then return
Record_Name
If there are 2 records (eg length of array = 2), then
check the field HasIP.
If HasIP = YesYes, then return the Record_Name of that matching entry
If HasIP = YesNo, then return the Record_Name of that matching entry.
If all else fails, return the number 2
This is what I'm up to at the moment.
=Switch(
'if no returns returned, display the numeral 2
LookupSet(Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2").Length=0, 2,
'if one return returned, then display Record Name
LookupSet(Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2").Length=1,
LookUp(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Record_Name.Value,"Dataset2"),
'if two records returned, check the HasIP field. If HasIP = YesYes, then use this combination first.
LookupSet(Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2").Length=2 AND
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!HasIP.Value,"Dataset2")(0)="YesYes",
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Record_Name.Value,"Dataset2")(0),
LookupSet(Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2").Length=2 AND
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!HasIP.Value,"Dataset2")(1)="YesYes",
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Record_Name.Value,"Dataset2")(1),
'if two records returned, check the HasIP field. If HasIP = YesNo, then use this combination second.
LookupSet(Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2").Length=2 AND
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!HasIP.Value,"Dataset2")(0)="YesNo",
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Record_Name.Value,"Dataset2")(0),
LookupSet(Fields!Main_ID.Value, Fields!Main_ID.Value, Fields!Record_Name.Value, "Dataset2").Length=2 AND
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!HasIP.Value,"Dataset2")(1)="YesNo",
LookUpSet(Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Record_Name.Value,"Dataset2")(1),
'If all else fails, display the number 2
True, 2)
I'm getting the correct one returned for 2 records, but getting #ERROR for zero and 1 records. If I break the formula down to their individual parts:
=SWITCH(
LookupSet(Fields!MainID.Value, Fields!MainID.Value, Fields!Record_Name.Value, "Dataset2").Length=0,
2)
This works. The number 2 is displayed in my report where the are no entries in Dataset2 (the field is blank for any other combination).
If I use:
=SWITCH(LookupSet(Fields!MainID.Value, Fields!MainID.Value, Fields!Record_Name.Value, "Dataset2").Length=1, LookUp(Fields!MainID.Value,Fields!MainID.Value,Fields!Record_Name.Value,"Dataset2"))
This works fine for when I have 1 record returned from Dataset2 (the field is blank for any other combination).
No matter what I tried with the third part (handling the 2 records), I'm getting issues. I can get the correct Record Name returned, but I'm getting #ERROR for 0 or 1 records.
I've tried nesting the third part in IIF statements, flipping it round to look at the length first, etc, but no success.
I cannot edit the underlying query of either dataset.
Any guidance much appreciated.
Solved
See:
SSRS 2012. Replicate grouping results in report in Query Designer
Essentially it was adding a numeric value to HasIP and also add in the Primary key of the second dataset.
Then sort the LookupSet array to get the value you want.
In the expression, you can use this to assign a default value, even when there are not results returned by the LookupSet:
=iif(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Main_ID.Value,"Dataset2"
).Length>0,
Mid(
Split(
Join(
Code.JoinSorted(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12b.Value,"Dataset2")
)
,";")
,";").GetValue(0)
, 'start point of mid
InStr(
Join(
Code.JoinSorted(
LookupSet(
Fields!Main_ID.Value,Fields!Main_ID.Value,Fields!Q12b.Value,"Dataset2"
)
)
,";")
,"$")
+1,
1),
"2"
)

Report and Graphic in access 2007 - calculating values on queries

Picture a table with fields (Id, Valid, Value)
Valid = boolean
Value = number from 0 to 100
What I want is a report that counts the number of records where (valid = 0), and then gives me the total number of cases where (value < 70) and the number of cases where (value >= 70).
The problem is that the "value" field could be empty on some of the records and I only want the records where the value field is not empty.
I know that the second value (value>=70) is going to be calculated, but the problem is that I can't simply do (total number of records - number of records where value < 70), because there's the problem with the records where "value" is null...
And then I want to create graphic with these values, to see the percentage of records below and above 70.
"The problem is that the "value" field could be empty on some of the records and I only want the records where the value field is not empty."
Use a WHERE clause to exclude rows whose "value" field is Null.
Here is sample data for tblMetraton.
Id Valid Valu
1 -1 2
2 0 4
3 -1 6
4 0
5 0 90
I used Valu for the field name because Value is a reserved word.
You can use the Count() function in a query and take advantage of the fact it only counts non-Null values. So use Count() with an IIf() expression which returns a non-Null value (I used 1) for the condition you want to match and Null otherwise.
SELECT
Count(IIf(Valid=0,1,Null)) AS valid_false,
Count(IIf(Valu<70,1,Null)) AS below_70,
Count(IIf([Valu]>=70,1,Null)) AS at_least70
FROM tblMetraton AS m
WHERE (((m.[Valu]) Is Not Null));
Based on my sample data in tblMetraton, that query gives me this result set.
valid_false below_70 at_least70
2 3 1
If my sample data does not address the variability you're dealing with, and/or if my query results don't match your requirements, please show us you own sample data and the results you want based on that sample.