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.
Related
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
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
I have a search screen which allows the user to search information and it populates a grid. Some of the search results are returning a huge amount of data. I am trying to create a paging grid so that I only bring from the store procedure 10 or 20 results at a time. (I already have a paging grid in the UI)
I am trying to do something like this:
select * from wl_eval limit 1, 20
The query above will return only the first 20 records. How would I be able to accomplish that in Sybase ASE? Unfortunately, for my client project we are using Sybase. I know that in other database engines we could have used the query I mention above. I also know we can use SET ROW COUNT 20 but this wont work if I want a particular range, say from 30 to 50.
Any thoughts?
Add TOP numberofrecords you want to return
DECLARE #intStartRow int;
DECLARE #intEndRow int;
SET #intStartRow = (#intPage -1) * #intPageSize + 1;
SET #intEndRow = #intPage * #intPageSize;
WITH wl_eval AS
(SELECT field,
ROW_NUMBER() OVER(ORDER BY intID DESC) as intRow,
COUNT(intID) OVER() AS intTotalHits
FROM tblBlog)
SELECT field, intTotalHits FROM wl
WHERE intRow BETWEEN #intStartRow AND #intEndRow
SELECT TOP 20 <column list>
FROM YourTable
ORDER BY <list>
Good day. I would like to know why a Parameter Request pops up when executing a query. I have a form with 2 comboboxes where the 2nd one depends on the value in the 1st one. I do know how to do this when it involves 2 tables. I am having trouble when there is a many to many relationship.
Table 1: name - Supply_Sources, fields - Source_ID(pk), SupplySourceName
Table 2: name - Warehouse_Locations, fields - WLocation_ID(pk), Location_Name
Table 3 (junction): name - SupplySource_WarehouseLocation, fields - Supply_Source_ID(pk), Location_In_ID(pk)
On my form frmInventoryReceivedInput I have cboSupplySource and cboWLocation.
I populate cboSupplySource with
SELECT [Supply_Sources].[Source_ID], [Supply_Sources].[SupplySourceName] FROM Supply_Sources;
I am trying to get a drop down list in the cboWLocation based on the value in cboSupplySource. I am wanting to see the location names of where the supplies are placed in the warehouse.
I have a requery in cboSupplySource After Update (with cboWLocation as the control name). The SQL that I have come up with so far is:
SELECT Warehouse_Locations.Location_Name,
SupplySource_WarehouseLocation.Supply_Source_ID,
SupplySource_WarehouseLocation.Location_In_ID
FROM Warehouse_Locations RIGHT JOIN (Supply_Sources LEFT JOIN
SupplySource_WarehouseLocation ON Supply_Sources.Source_ID =
SupplySource_WarehouseLocation.Supply_Source_ID) ON
Warehouse_Locations.WLocation_ID =
SupplySource_WarehouseLocation.Location_In_ID
WHERE (((Warehouse_Locations.Location_Name)=[frmInventoryReceivedInput].[cboSupplySource]));
When it runs, on tabbing out of cboSupplySource, Enter Parameter Value dialogue box pops up, looking for frmInventoryReceivedInput.cboSupplySource input. Nothing I input brings up the correct list in cboWLocation.
Obviously, I do not have the correct select statement. Any help would be appreciated.
For cboWLocation try the recordSource query:
SELECT Warehouse_Locations.Location_Name
FROM Warehouse_Locations INNER JOIN (Supply_Sources INNER JOIN
SupplySource_WarehouseLocation ON Supply_Sources.Source_ID =
SupplySource_WarehouseLocation.Supply_Source_ID) ON
Warehouse_Locations.WLocation_ID =
SupplySource_WarehouseLocation.Location_In_ID
WHERE ((Supply_Sources.SupplySourceName)=([Forms]![frmInventoryReceivedInput].[cboSupplySource]))
Be aware, that the combobox columns have to be set to columncount 1 in this case with appropriate column width, because you said you only want to see the location names. Further, you should be sure that cboWLocation is not bound to a Control Source, to not overwrite anything.
You can apply it in VBA at the cboWLocation Enter Event.
In the following code example, the combobox cboWLocation is only updated, if there is a value in combobox cboSupplySource.
Private Sub cboWLocation_Enter()
If not (isNull(Me!cboSupplySource) Or Me!cboSupplySource.ListIndex = -1) then
Me.cboWLocation.RowSource = strSQL 'Put here the previous mentioned SQLString
End if
End Sub
HINT: It would be better for performance, when you change the bound column in cboSupplySource to the PK SourceID instead of the name. (With two columns in combobox cboSupplySource) Then use this PK to compare in your WHERE statement instead of the name. this is what keys in tables are for.
Edit: In the WHERE statement, maybe you have to put the namecomparison between ' ' because it is a string
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