I am quite new to SSRS and have what I imagine is a pretty simple question. I have the set up pictured below.
What I'm looking for is a list of dates that data exists for then a nested list of outcomes and then how many of each of those outcomes there were on that date. What I get is this,
I want 6/10/2016 > ABORT > to be 3 instead of 1 1 1. What am I doing wrong? Is it possible that I need to change my query somehow?
Try using:
=COUNT(Fields!sys_OUTCOME.Value,"sys_OUTCOME")
If you don't want to see details rows delete the Details group in the Row Groups pane.
Code Explanation:
COUNT: Returns a count of non-null values specified by the expression,
evaluated in the context of the given scope.
REFERENCE
Every aggregation function can summarize data in a given context of the given scope. In this case the scope I passed to the COUNT function is "sys_OUTCOME" group name (Row Groups) so it will return the count of sys_OUTCOME values by sys_OUTCOME group. If you don't specify the group scope it will count every row without grouping what you was getting initially.
Let me know if this helps.
Related
I have a cross table in business objects web intelligence which has customer IDs in the rows, items in the columns and quantity in the body. I am trying to create a variable (dimension?) that will flag whether a customer has bought one particular item plus any other item. So, if for example the set item is 'item1' then the flag would show if the customer bought that and also if they bought at least one other item which could be any from another 100 or so. I am trying to write something that is akin to looking at two Booleans returning opposite results in the same statement.
if([item]="item1" And [quantity]>0;"Y";"")
and combine it with something like:
if([item]<>"item1" And [quantity]>0;"Y";"")
At the moment I can only get one or the other working and I can't then seem to create any further variable that would combine them because I end up with "Y" for all rows which is not correct. This is how the table might look after (mock-up in Excel):
I want to then be able to filter based on the flag results variable. Can anyone advise how I might address this problem?
You are really close. I defined count (or quantity) variables with where clauses. I created Var Select Item Count as...
=[quantity] Where ([item] = [your selected item])
And Var Other Items Count as...
=[quantity] Where ([item] <> [your selected item])
Finally, define your FLAG variable as...
=If([Var Select Item Count] > 0 And [Var Other Items Count] > 0; "Y")
Then you can filter on your FLAG variable.
Certainly, you could embed the code from the first two variables into the last one. However, I like to create my variables such that they build upon one other for easier understanding and maintenance.
Here is my example with "173" being the selected item.
I have a query that returns some dates which are not in any order. I need to select the last row from the sub query. The problem is all the solutions I can find online uses something like
ORDER BY qry_doc_dates.arrival_date DESC LIMIT 1
Select qry_doc_dates.arrival_date
FROM (qry_doc_date) AS qry_doc_dates
ORDER BY qry_doc_dates.arrival_date DESC
LIMIT 1
which will not serve my purpose because it first orders the dates as DESC(or ASC).
Suppose the qry_doc_date returns :
"2019-05-27",
"2019-05-13",
"2019-05-20",
"2019-05-22",
"2019-07-12",
"2019-05-22",
"2019-07-16",
"2019-05-22"
As we can see that the returned values are not in order. If I use
ORDER BY qry_doc_dates.arrival_date DESC LIMIT 1
then it returns "2019-07-16" But I need "2019-05-22" which is the last row.
EDIT 1:
I am trying to convert this VBA query to MYSQL.
DLast("arrival_date", "qry_doc_date", "[package_id] = " & Me!lstPackage)
I suppose I misunderstood what the VBA query wants to return. Another issue is I do not have means to run this VBA query and check the result myself.
Your question doesn't make too much sense according to the SQL standard. In the absense of an ORDER BY clause the database engine is free to return the rows in any order. This order may even change over time.
So essentially you are requesting the "last random row" the query returns. If this is the case, why don't you get the "first random row"? It doesn't make any difference, does it?
The only way of getting the last random row is to get them all and discard all of them except for the last one.
Now, if you just need one random row, I would suggest you just get the first random row, and problem solved.
In response to the additional information from your edit:
EDIT 1: I am trying to convert this VBA query to MYSQL.
DLast("arrival_date", "qry_doc_date", "[package_id] = " & Me!lstPackage)
I suppose I misunderstood what the VBA query wants to return. Another
issue is I do not have means to run this VBA query and check the
result myself.
Unless your dataset qry_doc_date is ordered by means of an order by clause, the DFirst or DLast domain aggregate functions will return essentially a random record.
This is stated in the MS Access Documentation for these two functions:
You can use the DFirst and DLast functions to return a random record from a particular field in a table or query when you simply need any value from that field.
[ ... ]
If you want to return the first or last record in a set of records (a domain), you should create a query sorted as either ascending or descending and set the TopValues property to 1. For more information, see the TopValues property topic. From a Visual Basic for Applications (VBA) module, you can also create an ADO Recordset object and use the MoveFirst or MoveLast method to return the first or last record in a set of records.
What you need is to in qry_doc_date to include a sequential row number.
Then you can use something like this:
ORDER BY qry_doc_dates.row_number DESC LIMIT 1
I need to get the first value within a large data-set, based on a row group where the condition holds true.
I.e: Get the First Value Where Deal Name is "ABC" and Type = "main" within a row group (scope) of a entire dataset.
I tried the following:
=IIF(Fields!DealName.Value="ABC" AND Fields!Type.Value="Main", First(Fields!DealValue.Value, "Deal"), NOTHING)
There are 3 records with distinct values for Deal Values.
In this scenario, it is picking up 0, when it should have picked up 4946.
Can I have the entire if statement in a scope?
Help would be immensely appreciated.
If I understand it right, you want to get first value based on if condition. Then you can use LookUp
Lookup(1, IIF(Fields!DealName.Value="ABC" AND Fields!Type.Value="Main", 1, NOTHING), Fields!DealValue.Value, "DateSetName")
This should be easy, but I am stuck.
I have a table listing some figures about Qualifications - to achieve which a dataset that is essentially a row per Student is being grouped on Qualification with a Parent Grouping on "Measure" (which is just a bucket of qualifications).
One of the columns is trying to work out the number of students (well, more properly the number of students with a value in a particular field, weighted by another field) in each Measure/Qualification. In the screenshot below, it's the "Pred. Avg" column on the right hand side.
So for the Qualification Row Grouping, that column is calculated by:
=CountDistinct(Iif(IsNothing(Fields!AVG_PTS.Value) = False, Fields!Learner_ID.Value, Nothing), "Qual") * Lookup(Fields!Qual_Code.Value, Fields!Qual_Code.Value, Fields!size.Value, "DS_KS5Nationals_LKP")
This works fine - the values of 35 and 11.5 in that rightmost column are correct for those rows. What the top row should be doing is simply adding up the values in the other rows to give me the number of students in this Measure, in this case to give 46.5. To do that the expression I am using is:
=Sum(CountDistinct(Iif(IsNothing(Fields!AVG_PTS.Value) = False, Fields!Learner_ID.Value, Nothing), "Qual") * Lookup(Fields!Qual_Code.Value, Fields!Qual_Code.Value, Fields!size.Value, "DS_KS5Nationals_LKP"), "Measure")
However as you can see in the screenshot, this returns 2917 instead.
So my question is; Why doesn't that work, and given that it doesn't work how can I, within a parent group, aggregate the results of aggregates inside a child group?
EDIT:
OK so, I have determined that the following works correctly:
=Sum(CountDistinct(Iif(IsNothing(Fields!AVG_PTS.Value) = False, Fields!Learner_ID.Value, Nothing), "Qual"), "Measure")
The problem there is that the Qual row that returns 11.5 is weighted to 0.5. I.E. it actually returns 23, and the Lookup(Fields!Qual_Code.Value, Fields!Qual_Code.Value, Fields!size.Value, "DS_KS5Nationals_LKP") is for that row returning 0.5 and altering it to 11.5...so the question becomes; "how do I force that ...*Lookup(Fields!Qual_Code.Value, Fields!Qual_Code.Value, Fields!size.Value, "DS_KS5Nationals_LKP") into the "Qual" scope, like the CountDistinct() is already in?
The issue here is that you're trying to aggregate values using that Lookup function which only returns one value. There are a couple ways you could go about doing this. One option would be to use the LookupSet function to get the applicable weightings. An even better option is to combine the data in your dataset so that the weighting is available without using a lookup. That way the function can recalculate an any grouping level without you having to force a scope on it. Also, CountDistinct ignores "Nothing" so you can do without the extra IIf statement. Hope that helps.
I'm back with another SSRS question :-)
I'm dealing with survey data. I have a procedure that's returning an organization's response counts per question. So my report is defined as Group on Organization for row and Group on answer for columns. Both the number of organizations and answers are variable. That's working as expected. I've tried adding a RowCount next to the organization so that I can show rank, but the fact that each org has one row per question means that I'm getting eight rows per org.
Here's an example:
Here is my report definition:
The rank expression is currently: =RowNumber(Nothing)
Ideally, the rank would be 1, 2, 3, 4, etc... I've tried scope to the row group, column group and nothing. No help.
Any assistance would be greatly appreciated!
Had same frustrating issue; lots of time wasted. Eventually, this solution also helped:
=RunningValue(CountDistinct("YourTableName"),Count,"YourTableName")
Trick here is NOT to use the name of the group within the table/matrix, but the name of the table itself. And yes, one would think that using the table name for the scope in the function RowNumber should work, but it doesn't.
Try using:
runningvalue(Fields!AnswerText.Value,CountDistinct,"NameOfOrganizationGroup")
If its a matrix, change the name of the scope from the row scope to the matrix scope.
I do with custom code.
Add this to code section on report config:
Dim private count as integer = 0
Dim private iniRow as integer = 0
Public function nroFila(Byval rowNum as integer) as integer
if iniRow = 0 then
iniRow = rowNum
end if
if rowNum = iniRow then
count = 0
end if
count = count + 1
Return count
End function
Then, call the function in a cell inside the group:
=Code.nroFila(RowNumber(Nothing))
I seem to have found a solution, but it feels like a hack... I'm leaving this unanswered to see if someone else can provide a better solution (read less hackish).
My Rank Expression is now:
=RowNumber(Nothing)/Count(Fields!AnswerText.Value)
Everything seems to be ok. I suppose I should IIf(Count... = 0, Then RowNumber, else what I've got...
Best thing to do here, is make the Rank column equal to =RowCount()/8
Since your sure each visible row contains a total of 8 rows, this should work fine.
Add another rank column next to the existing one and put another expression in that one which takes the value from rank (rowcount?) and divide it by 8. Then make the old rank column invisible.
Are you absolutely certain that using RowNumber("NameOfOrganizationGroup") doesn't work?
Click on the matrix, click the upper-left corner selection box to select the entire thing, then right-click on the selection border and get properties. Switch to the Groups tab and look at the names of the groups in the Rows section. That's what goes in the scope of the RowNumber() function.
If you already know this and tried it, my apologies—I didn't mean to assume you didn't know. It's just not 100% clear from your question that this is not the solution.
I got it by using a windowed function in the SQL query, this counts the row correctly within the column set.
dense_rank() over (partition by mgr.employee_sk order by e.employee_sk) as row_format
where mgr.employee_sk is my Lvl 2 Row Group, and e.employee_sk is my Lvl 3 Row Group (the detail level).
Then the SSRS expression then refers to this column from the query. To avoid it aggregating I used a min function, and to avoid it not displaying for rows that don't have data in all columns of the column group I specified the scope as my Level 3 Row Group.
=Iif(min(Fields!row_format.Value, "Employee") mod 2 = 1, "white", "aliceblue")