Optimization issue. How to check if a dataset is empty? - dataset

I'm designing a report where certain Detail bands should be printed only if they contain some data. This data is fetched by a separate query (dataset) for each band. I want to use the Print When Expression property to toggle Detail band visibility.
Is there a normal way to find out whether the dataset is empty for the report or do I have to write a crazy main query which will count rows for all datasets? That means actually duplicating queries from datasets which I'd like to avoid.
UPD:
The report is structured as follows:
A main query is called to prepare the base part of the report. This is the part which is always there.
Then there are a number of different queries (datasets) to the same datasource which may or may not return some data.
Data from each additional dataset is displayed in a table in a separate Detail band. Each detail band also contains some static content, such as labels and so on.
If the additional dataset returns no data, the entire Detail band should not be printed
------------------------------------------------------------------------
* Detail band 1.
*
* Contents of the main query here.
*-----------------------------------------------------------------------
* Detail band 2.
* Band label
* Contents of the additional dataset A in a table
*
* other static stuff
*-----------------------------------------------------------------------
* Detail band 3.
* Band label
* Contents of the additional dataset B in a table
*
* other static stuff
*-----------------------------------------------------------------------
* and so on
Here entire band 2 with all its contents should not be displayed in case there is nothing in additional dataset A

Related

Anylogic: How to create plot from database table?

In my Anylogic model I succesfully create plots of datasets that count the number of trucks arriving from terminals each hour in my simulation. Now, I want to add the actual/"observed" number of trucks arriving at a terminal, to compare my simulation to these numbers. I added these numbers in a database table (see picture below). Is there a simple way of adding this data to the plot?
I tried it by creating a variable that reads the database table for every hour and adding that to a dataset (like can be seen in the pictures below), but this did not work unfortunately (the plot was empty).
Maybe simply delete the variable and fill the dataset at the start of the model by looping through the dbase table data. Use the dbase query wizard to create a for-loop. Something like this should work:
int numEntries = (int) selectFrom(observed_arrivals).count();
DataSet myDataSet = new DataSet(numEntries);
List<Tuple> rows = selectFrom(observed_arrivals).list();
for (Tuple
row : rows) {
myDataSet.add(row.get( observed_arrivals.hour ), row.get( observed_arrivals.terminal_a ));
}
myChart.addDataSet(myDataSet);
You don't explain why it "didn't work" (what errors/problems did you get?), nor where you defined these elements.
(1) Since you want both observed (empirical) and simulated arrivals per terminal, datasets for each should be in the Terminal agent. And then the replicated plot (in Main) can have two data entries referring to data sets terminals(index).observedArrivals and terminals(index).simulatedArrivals or whatever you name them.
(2) Using getHourOfDay to add to the observed dataset is wrong because that just returns 0-23 (i.e., the hour in the current day for the current model date). Your database table looks like it has hours since model start, so you just want time(HOUR) to get the model time in elapsed hours (irrespective of what the model time unit is). Or possibly time(HOUR) - 1 if you only want to update the empirical arrivals for the hour at the end of that hour (i.e., at the same time that you updated the simulated arrivals).
(3) Using a Variable to get the database value each hour doesn't work because a variable's initial value is only evaluated once at model initialisation. You want an hourly cyclic Event in Terminal instead which adds the relevant row's value. (You need to use the Insert Database Query wizard to generate the relevant Java code for the query you need in the event's action.)
(4) Because you have a database table with specifically-named columns for each terminal (columns terminal_a and presumably terminal_b etc.) that makes it slightly more awkward. (This isn't proper relational table design where, instead of 4 columns for the 4 terminals, you'd instead have two columns for terminal_id and observed_value with a row for each time period and terminal combination.)
So your database query expression (in your Terminal agents) will need to use the SQL format (not the QueryDSL format) so that you can 'stitch in' the correct column name into the SQL.

How do I use multiple REGEXP_REPLACE uses in one formula?

I have a product sku coming into Data Studio from Google Analytics and I'm wanting to break it into dimension segments as it contains important information.
Here's a couple of example skus:
S00GX80-SU39-white-red cardinal-40
S00EN20-S903-yellow mustard-38
NOS-S000010-SF43-Navy-FWhit-39
The key information here is the colour and the size, coming towards the end of the SKU.
So far I've used this code to create a new dimension ('NEW SKU') to ensure all skus begin the same:
REGEXP_REPLACE(Product SKU,'NOS-','')
And then used the new dimension to create two new dimensions using the following formulas:
Colour - REGEXP_EXTRACT(New Product Sku, '^(?:[^-]*[-]){2}([^-]*)')
Size - REGEXP_EXTRACT(New Product Sku, '^(?:[^-]*[-]){3}([^-]*)')
These work to a certain extent except when there are extra dashes - in the sku. For instance using the SKU's from my original examples only the Yellow Mustard size 38 works correctly.
What I'm looking for is a formula that would take the colour out and a formula that takes the size out. The examples given would then look as follows:
Colour | Size
white-red cardinal | 40
yellow mustard | 38
Navy-FWhit | 39
I appreciate any help.
Since the values on the left and right sides are known, we can simply anchor based on those (also simplified to save you removing the NOS prefix by making it optional):
/* SKU */
REGEXP_EXTRACT(Product SKU,'(?i)^((?:NOS-)?[A-Z0-9]+-[A-Z0-9]+)')
/* Color */
REGEXP_EXTRACT(Product SKU,'(?i)^(?:(?:NOS-)?[A-Z0-9]+-[A-Z0-9]+)-(.+)-(?:[0-9]+)$')
/* Size */
REGEXP_EXTRACT(Product SKU,'([0-9]+)$')
Note that the $ assertion anchors to the end of the string just as ^ anchors to the beginning.
I would also add that using the Explore feature from the data source you can list the original SKU and the new calculated fields in a table grid, which makes it easy to identify any corner cases that need to be handled (e.g. filtering to where any of those calculated fields are blank to see what went wrong).
UPDATE: Here's what I get when running an explore against your examples (file upload source)

Is there any approach to get access the Sub report variable or to get SubReport element in main report?

I am writing an SSRS report in which I've a tablix that actually contain a subreport in one of its table cell. Now I want to understand to get this value as Sum on main report. For example, below is the student data:
Student Name | Total Subject | Obtained Marks (Sub Report)
XYZ | 6 | 35
ABC | 6 | 46
In above example, I am able to see the total marks of the first subject only. But I need to get the total form all 6 subjects from sub report. My tablix is already has Grouped by Student Name.
Below are the ways I tried to get it done:
Added another column in tablix and try to get the subreport as ReportItems! Subreport2, didn't work.
In the same column, I tried with Sum (Subreport2).
But since Subreport2 as report items are not accessible I'm not able to get it done.
UPDATE 1
I am using below expression to get sub-report value:
=ReportItems("Subreport2").value
The short answer is, no, you can't access fields from a subreport in the manner that you are attempting to. However, there is an easy way to get the values from that subreport that you may not have realized. The basic solution is to simply add another dataset to your report using the same query or stored procedure that is used in the subreport and getting the required data from that dataset. For example, you could then use a lookup function to match the data as needed. The lookup function requires four parameters detailed in the following expression.
= Lookup([SourceValue].Value, [DestinationValue].Value, [LookupValue].Value, "[DestinationDataset]")
The idea in your case would be to put your student name or ID field from the main report dataset in for source value, match that value in your subreport dataset for the destination value, get the value you need for lookup value, and the subreport dataset goes in parenthesis to indicate where to get the data from. So the following expression gives you an idea of what you need.
= Lookup(Fields!studentID.Value, Fields!studentIDSub.Value, Fields!ObtainedMarks.Value, "SubreportDataset")
Take a look at the documentation if you need any addition information.

Different drill through for each row

I have an SSRS report with several levels of drilling down. Data is aggregated up for the top level view, but I need to show a different drill down report depending on the type of one of the columns.
Eg:
Table 1 - Apples
Name Cost
Fuji 1.5
Gala 3.5
Table 2 - Squashes
Name Cost
Pumpkin 2
Gourd 4.5
I have a stored procedure which aggregates these and puts them in a table for the top level report to show. Ie:
Name Cost ItemType
Apples 5 1
Squashes 6.5 2
In reality, the two tables have different columns which I need to show in the drill through reports. Is it possible to look at the ItemType column and either drill down to one of two sub-reports, depending on it's value?
If you need to choose between two or more different sub-reports then make the ReportName property of the action on the textbox an expression like this.
=IIF(Fields!ItemType.Value = 1, "subReport_Apples", "subReport_Oranges")
if you have more than a handful SWITCH will probably be better
= SWITCH (
Fields!ItemType.Value = 1, "subReport_Apples",
Fields!ItemType.Value = 2, "subReport_Oranges",
Fields!ItemType.Value = 3, "subReport_Lemons",
True, "subReport_AnythingElse"
)
If you have a LOT of item types, consider adding the names of the subreports to your database creating a new table containing ItemType and subReportName. You can then join to this in your query and get the actual subreport name. The ReportName property of the text action would then simply be Fields!SubReportname.Value
You can add the ItemType as a parameter in your subreport(s). Then from your main report just link or jump to the sub report and pass along the Fields!ItemType.Value in the parameter configuration tab.

Taking too long to retrieve and display the result in the telerik grid.

I have a MVC application in which I need to display the data from 3 tables. I am using entity model for it. Out of these, in 2 I have made the association:users and payment table.
And 3rd table month_<monthid> is created every month to store the users to whom the magazine is sent. The table name month_<monthid> is generated dynamically by selecting the month so in order to fetch the data I have used ExeuteStoreQuery. For small amount of data the listing is fast but for large amount it is very slow.
Now I have created a class to bind to grid which will include all the fields from the 3 tables to display.
But here when I am getting the large volume of data about 12000 then it is taking about 30 min to go through the loop and assigning the data to the class object and then adding to the list of the result which is finally binded to telerik grid.
I am hereby attaching the sample code using a link. Is there any direct way to bind the query result of joined tables to grid instead of going through the loop and preparing the list for the model class I think that will save time.
The code block of preparing the list using the Executestorequery is under the function GetuserList().
foreach (var r in result)
{
Result objresult = new Result();
var paymentresult = from sub in dtpayment.AsEnumerable() where sub.Field<int>("user_id") == r.user_id select sub;
if (paymentresult.Count() > 0)
{
objresult.amount_paid = paymentresult.FirstOrDefault().Field<decimal>("amount_paid");
objresult.magzine_id = paymentresult.FirstOrDefault().Field<int>("magzine_id");
}
objresult.address=r.address;
objresult.email=r.email;
objresult.name=r.name;
objresult.user_id=r.user_id;
objresult.month= smonth;
lstresult.Add(objresult);
}
This code block of for loop is taking very time where I am using ExceuteStoreQuery.
But I have observed that simply by joining the users and payment table using LINQ query to get all the 12000 records i.e no involvement of month table the result is appearing faster.
So,can you suggest any way to improve the performance of my application?
Also include the database structure with the sample code.
Below is the link to sample
http://sampletestone.s3.amazonaws.com/magzine.7z?AWSAccessKeyId=AKIAINHDRCMKC5GUSNFA&Expires=1303583399&Signature=8o8Wn6UNjbEl3dIyipAX9xH29Hg%3D
supriya
Nobody in the world wants to see 12,000 records. You should look at implementing paging & searching functionality.

Resources