How to use multiple conditions (With AND) in IIF expressions in ssrs - sql

I want to hide rows in SSRS report having Zero Quantity.
There are following multiple Quantity Columns like Opening Stock, Gross Dispatched,Transfer Out, Qty Sold, Stock Adjustment and Closing Stock etc.
I am doing this task by using following expression:
=IIF(Fields!OpeningStock.Value=0 AND Fields!GrossDispatched.Value=0 AND
Fields!TransferOutToMW.Value=0 AND Fields!TransferOutToDW.Value=0 AND
Fields!TransferOutToOW.Value=0 AND Fields!NetDispatched.Value=0 AND Fields!QtySold.Value=0
AND Fields!StockAdjustment.Value=0 AND Fields!ClosingStock.Value=0,True,False)
But by using this expression in row visibility, report hides all the rows except Totals Row. Even though report should show rows having Quantities of above mentioned columns.
Total values are shown correct.
Note: I set this row visibility expression on Detail Row.
Without using expression result is as following.
For the first 2 rows all the quantities are 0 (ZERO), i want to hide these 2 rows.
How can I fix this problem, or which expression must I use to get required results?

Could you try this out?
=IIF((Fields!OpeningStock.Value=0) AND (Fields!GrossDispatched.Value=0) AND
(Fields!TransferOutToMW.Value=0) AND (Fields!TransferOutToDW.Value=0) AND
(Fields!TransferOutToOW.Value=0) AND (Fields!NetDispatched.Value=0) AND (Fields!QtySold.Value=0)
AND (Fields!StockAdjustment.Value=0) AND (Fields!ClosingStock.Value=0),True,False)
Note: Setting Hidden to False will make the row visible

You don't need an IIF() at all here. The comparisons return true or false anyway.
Also, since this row visibility is on a group row, make sure you use the same aggregate function on the fields as you use in the fields in the row. So if your group row shows sums, then you'd put this in the Hidden property.
=Sum(Fields!OpeningStock.Value) = 0 And
Sum(Fields!GrossDispatched.Value) = 0 And
Sum(Fields!TransferOutToMW.Value) = 0 And
Sum(Fields!TransferOutToDW.Value) = 0 And
Sum(Fields!TransferOutToOW.Value) = 0 And
Sum(Fields!NetDispatched.Value) = 0 And
Sum(Fields!QtySold.Value) = 0 And
Sum(Fields!StockAdjustment.Value) = 0 And
Sum(Fields!ClosingStock.Value) = 0
But with the above version, if one record has value 1 and one has value -1 and all others are zero then sum is also zero and the row could be hidden. If that's not what you want you could write a more complex expression:
=Sum(
IIF(
Fields!OpeningStock.Value=0 AND
Fields!GrossDispatched.Value=0 AND
Fields!TransferOutToMW.Value=0 AND
Fields!TransferOutToDW.Value=0 AND
Fields!TransferOutToOW.Value=0 AND
Fields!NetDispatched.Value=0 AND
Fields!QtySold.Value=0 AND
Fields!StockAdjustment.Value=0 AND
Fields!ClosingStock.Value=0,
0,
1
)
) = 0
This is essentially a fancy way of counting the number of rows in which any field is not zero. If every field is zero for every row in the group then the expression returns true and the row is hidden.

Here is an example that should give you some idea..
=IIF(First(Fields!Gender.Value,"vw_BrgyClearanceNew")="Female" and
(First(Fields!CivilStatus.Value,"vw_BrgyClearanceNew")="Married"),false,true)
I think you have to identify the datasource name or the table name where your data is coming from.

Related

Add new column in SQL based on 2 conditions

I would like to create a new column in SQL using two conditions. I want to create a column that says 1 if the item count is greater than 1 and if item/sum is greater than 5, otherwise return 0. This is not my original data, is there anyway I could add this new column with these specified rows using a select statement.
First I want to say that using SQL key words or SQL function names as table name or column name should be avoided, so if possible, I recommend to rename the columns "number" and "sum".
The second point is it's unclear what should happen in case the sum column is 0. Since a division by zero is not possible, you will need to add a condition for that.
Anyway, the way to achieve such things is using CASE WHEN. So let's add the new column:
ALTER TABLE yourtable ADD column column_name INT;
Now, you need to execute an update command for that column providing the logic you want to apply. As an example, you can do this:
UPDATE yourtable SET column_name =
CASE WHEN item <= 1 THEN 0
WHEN sum = 0 THEN 1
WHEN item / sum > 0.5 THEN 1
ELSE 0 END;
This will set the new column to 1 only in case item is > 1 and sum is 0 or sum item / sum is > 0.5 (greater 50%). In all other cases it will be set to 0. Again, the bad column naming can be seen since "WHEN sum..." looks like you really build a sum and not just use a column.
If you want as example to set the new column to 0 instead of 1 when the sum is 0, just change it and try out.
In case you want to automatically apply this logic fur future inserts or updates, you can add a trigger on your new column. Something like this:
CREATE TRIGGER set_column_name
BEFORE INSERT ON yourtable
FOR EACH ROW
SET new.column_name = CASE WHEN new.item <= 1 THEN 0
WHEN new.sum = 0 THEN 1
WHEN new.item / new.sum > 0.5 THEN 1
ELSE 0 END;
But take care, the syntax of triggers depend on the DB you are using (this example will work in MYSQL). Since you did not tell us which DB you use, you maybe need to modify it. Furthermore, depending on your DB type and your requirements, you need zero, one or two triggers (for updates and for inserts).

SQL Query getting not results

I have a Select statement that gets the items based on the greatest date. it works but these are selected value from asp.net controls and one of the controls is a multiselect listbox
as you can see DynamicAtrributeID 937766 is show one time:
I need it to show all the rows that were in 937766 as well as the other rows which could be just one row. Is this possible
SELECT VotingValueDynamicId,
DecisionValueID,
DynamicAttributeID,
VotingValue,
DecisionSurveyID,
VALUEDATEUPDATED,
RECORDSTATUS,
FROM Adjudicate.ONCOLOGY_DynamicDecisionValuesForCaseManager AS a
WHERE (VALUEDATEUPDATED =
(SELECT MAX(VALUEDATEUPDATED) AS Expr1
FROM Adjudicate.ONCOLOGY_DynamicDecisionValuesForCaseManager AS b
WHERE (a.DecisionValueID = DecisionValueID) AND a.DynamicAttributeID = DynamicAttributeID) ) AND (RECORDSTATUS <> 'D')
In the example shown, all the rows with DynamicAtrributeID = 937766 have different values on VALUEDATEUPDATED, so the query is showing one row for that DynamicAtrributeID because that's what you're doing, filtering and getting only the row wich has the max VALUEDATEUPDATED.
In other words, you can't get more than one row for a DynamicAtrributeID if you're filtering by his max(VALUEDATEUPDATED).
As #necoflecap1 said , the issue is your filter condition, For VALUEDATEUPDATED , you are filtering max(VALUEDATEUPDATED) which any way going to give 1 value per DynamicAttributeID and DecisionValueID combination,since your filter in subquery is
WHERE (a.DecisionValueID = DecisionValueID) AND (a.DynamicAttributeID =
DynamicAttributeID)
I can see two possibilities here , either add one more filter for VotingValue column
WHERE (a.DecisionValueID = DecisionValueID) AND (a.DynamicAttributeID =
DynamicAttributeID) and (a.VotingValue=b.VotingValue)
or Do a
group By VotingValue
inside filter subquery for max(VALUEDATEUPDATED) so that aggregation will perform for every VotingValue (which is the column I can see coming with a different value for DynamicAtrributeID 937766)

SQL Subquery with Conditional Modulo

I've put together this query and I am struggling to see why it is returning the full quantity of LINES rather than just the LINES that have an odd number of ITEMS. Ex: right now I have 2 LINES where COMPLETED is marked True. One of them has an odd number of ITEMS and one of them has an even number of ITEMS but the query is still returning 2 despite my conditional. What's wrong with my query?
SET #linesCompleted = (SELECT Count([so_line_number]) AS LINES
FROM [aof_order_line_queue]
WHERE [completed] = 'True'
AND (SELECT Count([serial_number]) AS ITEMS
FROM [aof_order_items]
WHERE so_line_number IN (SELECT
[so_line_number]
FROM
[aof_boxes_lines]
WHERE
[aof_boxes_id] = 880)) % 2 = 1)
The goal here is to compute the quantity of LINES that a box contains that are an odd number.
I suspect the problem could the IN subquery returning two results, though one result should be odd and one result should be even.
The problem is the lack of correlation in the outer query to the inner query.
You are asking it to count the number of lines in aof_order_line_queue where (something that's not related to the line) is true. So the thing in the parenthesis is either true or false for the whole data set, not for each line. If it's true, it will count all the lines. If it's false, it will return 0.
You have to add something like
AND aof_order_items.queue_id = aof_order_line_queue.queue_id
to your inner query.

Pivot Table Independent Grand Total Row

Is it possible to have a grand total row in a pivot table that is independent of selections? The table I am currently working with has region & branch dimensions and then several columns of data. I would like the company total to display at the bottom row regardless of what regions and/or branches are selected.
You can use Dimensionality() function.
As you can see from the picture below the rows have Dimensionality() = 2 and the total row have Dimensionality() = 0
So in your case the expression will be something like this:
if( Dimensionality() = 0,
sum( {< Region=, Branch= >} Value),
sum( Value )
)
(Don't forget to remove/disable the Dimensionality() column to test it. If not removed the chart will not behave as normal)
Using the above expression the total row will show the sum( Value ) ignoring the selections in Region and Branch fields:
Also you can see that Dimensionality() is changing depends on the table aggregation. For example when collapse the Region the Dimensionality() function is returning 1 for the rows:
No need to tell you that if you have decent amount of data such expressions will decrease the performance!
There is also and SecondaryDimensionality() function which is basically the same as Dimensionality() but for the horizontal pivot dimensions.
An easier way of accomplishing this would be to have a straight table directly below your pivot table using set analysis to exclude selections.

SSRS CountRows of a specific Field containing a specific Value

I am building an SSRS report. I have a DataSet that contains several Fields, one of which is Doc_Type. Doc_Type can contain several values, one of which is 'Shipment'.
In my report, I want to count the number of Doc_Types that are equal to 'Shipment'. This is what I am using, and it is not working:
=CountRows(Fields!Doc_Type.Value = "Shipments")
The error I get is: "The Value expression for the textrun 'Doc_Type.Paragraphs[0].TextRuns[0]' has a scope parameter that is not valid for an aggregate function. The scope parameter must be set to a string constant that is equal to either the name of a containing group, the name of a containing data region, or the name of a dataset.
You need to use an IIF to evaluate your fields and SUM the results. If your expression is in a table, you could use this:
=SUM(IIF(Fields!Doc_Type.Value = "Shipments", 1, 0))
There are many ways to achieve this.
Method 1
You can set up your expression something like this
=SUM(IIf(Fields!Doc_Type.Value = "Shipments", 1, 0), "YourDataSetName")
Remember SSRS is case sensitive so put your dataset name and Field names correctly.
Method 2
I prefer handling it in SQL as I want to keep the business logic out of RDLs.
You can use window functions to get the shipment count.
Also notice in the case of count I haven't added ELSE 0 condition. Because that will give wrong results. Count doesn't care what is the value inside it. It just counts all Non Null values. ELSE NULL will work.
SELECT Column1, Column2, Column3,
SUM(CASE WHEN Doc_Type = 'Shipments' THEN 1 ELSE 0 END) OVER() ShipmentCount_UsingSum
COUNT(CASE WHEN Doc_Type = 'Shipments' THEN 1 END) OVER() ShipmentCount_UsingCount
FROM myTable
JOIN....
WHERE .....
Now you can use this field in the report.