SSRS Serial Numbering a static row within a group - sql-server

I created a group within a table on SSRS
I used < =rownumber(nothing) > to auto serial the detailed row
the problem is that I need to generate another auto serial for the static row within the group to start from 1 and increasing by 1 according this static row only
I tried using code.
Public rn as Integer
Public Function GetRn() AS Integer
rn = rn +1
return rn
End Function
It worked fine, but it starts from 1 for each new page of the report
I also notice it started from 433 if it's printed as pdf or exported as pdf.
find the attached pic
the required result

Add an expression to the textbook.
=RowNumber("YourRowGroupNameHere")

Related

How to merge multiple records with strings and nulls in a Stream Analytics Group By

I am trying to pull some logged events from Application Insights into our SQL database. I have no control over the format of the inputs which are json files composed of multiple json arrays within the file. In each record, 5 pieces of information are in a json array at [context].[custom].[dimensions] in the file and using an OUTER APPLY flattens these values. The problem is it returns results not as one row per record but as though you had joined one row with 5 (which is indeed what it has done) and the values of the 5 pieces of data are NULL in 4 cases and the actual value in the other. I only need 2 of the 5 values - PageType and UserId - and given this in my GROUP BY it returns 3 records, one with each value and one with both of them null.
In normal SQL you would simply use a MAX expression to get the real values for each but in Stream Analytics you can't use MAX on strings. You also can't use COALESCE and a number of other methods I tried to resolve this with. Any ideas how the results can be changed from:
EventDateTime Event PageType UserId AppVersion CountA
2017-05-24 Nav Show NULL NULL 2.0.1293 1
2017-05-24 Nav Show NULL SIRTSW 2.0.1293 1
2017-05-24 Nav Show Trade NULL 2.0.1293 1
to
2017-05-24 Nav Show Trade SIRTSW 2.0.1293 1 ?
The code that returns three rows for each is as follows (note that e.event is an array of one item so it does not cause the same issue):
SELECT flatEvent.ArrayValue.name as Event,
e.context.data.eventTime as EventDateTime,
e.context.application.version as AppVersion
,flatCustom.ArrayValue.UserId as UserId
,flatCustom.ArrayValue.PageType as PageType,
SUM(flatEvent.ArrayValue.count) as CountA
INTO
[insights]
FROM [ios] e
CROSS APPLY GetArrayElements(e.[event]) as flatEvent
OUTER APPLY GetArrayElements(e.[context].[custom].[dimensions]) as flatCustom
GROUP BY SlidingWindow(minute, 1),
flatEvent.ArrayValue.name,
e.context.data.eventTime,
e.context.application.version,
flatCustom.ArrayValue.UserId,
flatCustom.ArrayValue.PageType
Thanks in advance,
Rob
According to your scenario, I assumed that you could use JavaScript user-defined functions for Azure Stream Analytics to coalesce the multiple dimensions into a single record. Here are my test for this issue, you could refer to them.
JSON file
{
"context":{
"data":{"eventTime":"2017-05-24"},
"application":{"version":"2.0.1293"},
"custom":{
"dimensions":[
{"PageType":null,"UserId":"SIRTSW"},
{"PageType":"Trade","UserId":null},
{"PageType":null,"UserId":null}
]
}
},
"event":[
{"name":"Nav Show","count":1}
]
}
javascript UDF, UDF.coalesce
function main(items) {
var result=[];
var UserIdStr="",PageTypeStr="";
for(var i=0;i<items.length;i++){
if(items[i].UserId!=null && items[i].UserId!=undefined)
UserIdStr+=items[i].UserId;
if(items[i].PageType!=null && items[i].PageType!=undefined)
PageTypeStr+=items[i].PageType;
}
result.push({UserId:UserIdStr,PageType:PageTypeStr});
return result;
}
Query
--first query
WITH f AS (
SELECT
e.context.data.eventTime as EventDateTime,
e.context.application.version as AppVersion,
e.event as flatEvent,
UDF.coalesce(e.[context].[custom].[dimensions]) as flatDimensions
FROM [ios] e
)
--second query
SELECT flatEvent.ArrayValue.name as Event,
f.EventDateTime,
f.AppVersion,
flatDimension.ArrayValue.UserId,
flatDimension.ArrayValue.PageType,
SUM(flatEvent.ArrayValue.count) as CountA
FROM f
CROSS APPLY GetArrayElements(f.[flatEvent]) as flatEvent
OUTER APPLY GetArrayElements(f.[flatDimensions]) as flatDimension
GROUP BY SlidingWindow(minute, 1),
flatEvent.ArrayValue.name,
f.EventDateTime,
f.AppVersion,
flatDimension.ArrayValue.UserId,
flatDimension.ArrayValue.PageType
TEST RESULT

Decrease execution time of SQL query

I've got a question in terms of processing and making a query more efficient whilst maintaining its accuracy. Before I display the query I'd like to point out some basics of it.
I've got a case that manipulates the where-clause to get all childs of the parent. Basically I've got two types of data that I need to display; a red and a green type. The red type has a column (TRK_TrackerGroup_LKID2) set to NULL by default, whereas the green data has a value in said column (ranging from 5-7).
My problem is that I need to extract both types of data to accurately get a count of outstanding issues in a view, but doing so (by adding the case) the execution time goes from < 1 second to well over 15 seconds.
This is the query (with the mentioned case):
SELECT TS.id AS TrackerStartDateID,
TSM.mappingtypeid,
TSM.maptoid,
TFLK.trk_trackergroup_lkid,
Count(TF.id) AS Cnt
FROM [dbo].[trk_startdate] TS
INNER JOIN [dbo].[trk_startdatemap] TSM
ON TS.id = TSM.trk_startdateid
AND TSM.deletedflag = 0
INNER JOIN [dbo].[trk_trackerfeatures] TF
ON TF.trk_startdateid = TS.id
AND TF.deletedflag = 0
INNER JOIN [dbo].[trk_trackerfeatures_lk] TFLK
ON TFLK.id = TF.trk_feature_lkid
WHERE TS.deletedflag = 0
AND TF.applicabletoproject = 1
AND TF.readyforwork = CASE -- HERE IS THE PROBLEM
WHEN TF.trk_trackerstatus_lkid2 IS NULL THEN 0
ELSE 1
END
AND TF.datestamp = (SELECT Max(TF2.datestamp)
FROM [dbo].[trk_trackerfeatures] TF2
INNER JOIN [dbo].[trk_trackerfeatures_lk] TFLK2
ON TFLK2.id = TF2.trk_feature_lkid
WHERE TF.trk_startdateid = TF2.trk_startdateid
AND TFLK2.trk_trackergroup_lkid = TFLK.trk_trackergroup_lkid)
GROUP BY TS.id,
TSM.mappingtypeid,
TSM.maptoid,
TFLK.trk_trackergroup_lkid,
TF.datestamp
It functions as a 'parent' in the sense that it grabs the latest inserted data-set (using DateStamp) from every single child-group. This is necessary to produce a parent-report in SSRS report at a later time, but at the moment my problem (as mentioned above) is the execution time.
I'd like to hear if there are any suggestions on how to decrease the execution time whilst maintaining the accuracy of the query.
Expected output:
Without the case I get this:
Your problem is this condition cant use INDEX
AND TF.readyforwork = CASE -- HERE IS THE PROBLEM
WHEN TF.trk_trackerstatus_lkid2 IS NULL THEN 0
ELSE 1
END
Try to change it to
AND ( TF.readyforwork = 0 and TF.trk_trackerstatus_lkid2 IS NULL
OR TF.readyforwork = 1 and TF.trk_trackerstatus_lkid2 IS NOT NULL
)
But again you should check with EXPLAIN ANALIZE to test if your query is using index or not.
The most problematic bit of your query seems to be the correlated subquery, because you must call it for every possible row.
You should optimize this first. To do so you can add indexes that the engine could use to quickly calculate that value on each row.
Based on your query I would add these two indexes multiples :
On Table trackerfeatures, index fields : trk_startdateid, datestamp
On Table trk_trackerfeatures_lk, index fields : id, trk_trackergroup_lkid

NHibernate ORDER BY CURRENT_TIMESTAMP conflicts with DISTINCT

Could anybody please explain why NHibernate on MsSql2012Dialect generates query that can not be processed by server? It builds query this way when there is no sorting specified explicitly.
...
ORDER BY CURRENT_TIMESTAMP
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY
This is unresolved bug registered in jira, based on the suggestions, this is my work around:
public class MyMsSql2012Dialect : MsSql2012Dialect
{
public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
{
var result = base.GetLimitString(querySqlString, offset, limit);
return result.Replace("ORDER BY CURRENT_TIMESTAMP", "ORDER BY 1");
}
}
As you said in the question, following query is generated if no ORDER BY is explicitly specified:
SELECT
distinct this_.ColumnName as y0_
FROM
[DB].[dbo].Table this_
ORDER BY
CURRENT_TIMESTAMP OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
Error is:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
Error only occur if BOTH Projections.Distinct and Take(1) is provided and SQL Server version is above 2012 (Dialect is MsSql2012Dialect or above).
The better solution is to provide the ORDER BY column to NHibernate explicitly and include that column in SELECT list.
Session.QueryOver<Entity>()
.Select(
Projections.Distinct(Projections.Property<Entity>(x => x.ColumnName))
)
.Where(....)
.OrderBy(Projections.Property<Entity>(x => x.ColumnName)).Asc()
.Take(1);

Display the result and the details separately in SSRS 2012

I have a report in SSRS 2012 which count the number of rows (nb_flow et nb_GPFlow) of 2 DataBase
with this script
SELECT (SELECT rows
FROM sys.sysindexes
WHERE (id = OBJECT_ID('BentekDatabase.dbo.flow')) AND (indid < 2))
AS nb_flow,
(SELECT COUNT(OriginId) AS Expr1
FROM DataWarehouse.dbo.GPFlow
WHERE (LoaderCode = 'BTK'))
AS nb_GPFlow
and I added a calculated field (Test_Equal) to compare the 2 numbers of rows, Test_Equal expression = =IIF(Fields!nb_GPFlow.Value = 3* Fields!nb_flow.Value, "OK", "NOK" )
When I run the script it works perfectly, but I want to put the Test_Equal as the first result and when I click to the field in goes to another tab which display the other 2 fields (nb_flow , nb_gpflow)
Any help?
To force a hard page break you should put all elements that you want on page 1 in a Rectangle control, see Toolbox-->Rectangle. Make sure you set the PageBreak.BreakLocation property of the Rectangle to break after it is rendered. You may want to add another Rectangle for page two.

Loop 5 records at a time and assign it to variable

I have a table of 811 records. I want to get five records at a time and assign it to variable. Next time when I run the foreach loop task in SSIS, it will loop another five records and overwrite the variable. I have tried doing with cursor but couldn't find the solution. Any help will be highly appreciated. I have table like this for e.g.
ServerId ServerName
1 Abc11
2 Cde22
3 Fgh33
4 Ijk44
5 Lmn55
6 Opq66
7 Rst77
. .
. .
. .
I want query should take first five names as follows and assign it to variable
ServerId ServerName
1 Abc11
2 Cde22
3 Fgh33
4 Ijk44
5 Lmn55
Then next loop takes another five name and overwrite the variable value and so on till the last record is consumed.
Taking ltn's answer into consideration this is how you can achieve limiting the rows in SSIS.
The Design will look like
Step 1 : Create the variables
Name DataType
Count int
Initial int
Final int
Step 2 : For the 1st Execute SQL Task write the sql to store the count
Select count(*) from YourTable
In the General tab of this task Select the ResultSet as Single Row.
In the ResultSet tab map the result to the variable
ResultName VariableName
0 User::Count
Step 3 : In the For Loop container enter the expression as shown below
Step 4 : Inside the For Loop drag an Execute SQL Task and write the expression
In Parameter Mapping map the initial variable
VariableName Direction DataType ParameterName ParameterSize
User::Initial Input NUMERIC 0 -1
Result Set tab
Result Name Variable Name
0 User::Final
Inside the DFT u can write the sqL to get the particular rows
Click on Parameters and select the variable INITIAL and FINAL
if your data will not be update between paging cycles and the sort order is always the same then you could try an approach similiar to:
CREATE PROCEDURE TEST
(
#StartNumber INT,
#TakeNumber INT
)
AS
SELECT TOP(#TakeNumber)
*
FROM(
SELECT
RowNumber=ROW_NUMBER() OVER(ORDER BY IDField DESC),
NameField
FROM
TableName
)AS X
WHERE RowNumber>=#StartNumber

Resources