Running values for whole chart - reporting-services

I ran with a bit of a problem with SSRS and I would like to ask if you encountered this previously. The report requirement for the report is to show a graph that looks like this.
What I did was I made a Category group for the date value and Series Group for the data shown in Red and Blue. The issue I am having is representing the line pointed in the picture. When I tried to do it in SSRS, it generates N times based on how data the Series Group has. See screenshot below:
My question is would it be possible to ignore the groupings in the expression formula or somewhere so that the running value for both of the series groups in one line?

I was unable to do it on SSRS so I decided to do it in T-SQL instead. I added a column to be used as the value for the running table
WITH t as(
SELECT SUM(Value1) AS 'RunningValue',
[Date]
FROM Table1
WHERE [Group] IN ('Group1', 'Group2')
GROUP BY [Date]
)
SELECT
x.*, t.RunningValue
FROM(
SELECT
[Group],
[Date],
[Description] AS [Description],
SUM(Value1) AS Value1,
SUM(Value2) AS Value2,
SUM(Value3) AS Value3
FROM Table1
GROUP BY [Date], [Group], [Description]
) x
CROSS APPLY t WHERE t.[Date] = x.[Date]
The downside of using this is that it is that it becomes expensive when the table grows as i am basically querying twice.
I also used the link https://social.msdn.microsoft.com/Forums/sqlserver/en-US/74d9affc-ebf3-485c-988e-f28f7049b600/how-to-make-one-of-the-chart-ignore-series-grouping?forum=sqlreportingservices provided by #StrawberryShrub to hide the duplicate line in the graph. Thanks all!

Related

SSRS access fields in a dataset

I want to write a SSRS expression that will allow me to grab the value from Column B base on the max value from ColumnA.
For Example, I have the following values
ColumnA
ColumnB
1
Test
2
Tester
3
Testing
=FIRST(
iif(
Fields!ColumnA.Value= MAX(Fields!ColumnA.Value,"test"),
Fields!ColumnB.Value,0
),"test"
)
The reason I am doing this is because I am trying to combine to datasets in one table. Certain fields in the table just needs to select top N values from another dataset.
I think that easiest way is to add something like row_number into your sql query (row_number() over (order by ColumnA desc) rn and then you can have condition iif(fields!rn.value = 1, fields!ColumnB.value,0)

How to SUM the values from group in SSRS which are distinct

I have a report where I want to calculate the Grand total but ignore the values of a group which have same value. Below are my tables and the data. The Package No column is grouped and will be unique always, but every unique Package may or may not have same dimensions. I want to SUM the dimension (Length, Width and Height) and it Package No has multiple items in it then have to consider only the first row for summing up the values as the dimensions will remain the same for all the items within the same Package. Can anyone please help me to achieve this result?
Assuming the data that gets returned from your dataset query looks like the sample you show in the image then you should be able to do something like...
=SUM(IIF(Fields!RowNum.Value = 1, Fields!Length.Value, 0))
EDIT after OP update
If the RowNum column is not in your dataset then you will need to add it.
If you dataset query is just a script then it should be as easy as something like this...
SELECT *
, RownN = ROW_NUMBER() OVER(PARTITION BY PackageNo ORDER BY Item)
FROM myTable
If the dataset is the result of a stored proc then you might have to change the dataset query to something like
CREATE TABLE #t (PackageNo varchar(50), Length int, Width int, Height int, Item varchar(50))
INSERT INTO #t
EXEC myStoredProc
SELECT *
, RownN = ROW_NUMBER() OVER(PARTITION BY PackageNo ORDER BY Item)
FROM #t
Once one of the above options are been taken then you should be able to simply apply the =SUM(IIF(Fields!RowN.Value = 1, Fields!Length.Value, 0))
expression in your report totals.

DB2 - LISTAGG() with DISTINCT clause - doesn't work?

My query has a column with a small number of values in it, and I need to display them in a single field for each grouped result set - e.g. if I had an employee in 3 different departments, I'd want to see something like
EMPID DEPTS SOMENUMBER SOMEOTHERNUMBER
------ ------ ----------- ---------------
0001 ACCOUNTING, CUST SERVICE, CALL CENTER 100 200
The problem is when there are multiple duplicate departments for the employee. I see numerous questions on how to figure this out for Oracle and other DMBSs, but nothing specific to DB2. IBM's own documentation at https://www.ibm.com/support/knowledgecenter/SSFMBX/com.ibm.swg.im.dashdb.sql.ref.doc/doc/r0058709.html says:
- "If DISTINCT is specified, duplicate string-expression values are eliminated.", and
- "If DISTINCT is specified for LISTAGG, the sort-key of the ORDER BY specification must match string-expression (SQLSTATE 42822). If string-expression is implicitly cast, the sort-key must explicitly include a corresponding matching cast specification.".
As a simplistic example:
with mylist (field1) as
( values 'A','A','B','C','D','A','C'
)
select listagg (distinct field1, ', ')
within group (order by field1)
from mylist;
The info on the IBM page suggests that this should return 'A, B, C, D' but instead I get 'A. A. A. B, C. C, D'.
I should be able to get around this by having a subquery do some initial rolling up - e.g.
SELECT EMPLOYEE, LISTAGG(DEPARTMENT,', '),
SUM(SOMENUMBER) SOMENUMBER, SUM(SOMEOTHERNUMBER) SOMEOTHERNUMBER
from (
SELECT EMPLOYEE, DEPARTMENT, SUM(SOMENUMBER) SOMENUMBER, SUM(SOMEOTHERNUMBER) SOMEOTHERNUMBER
FROM EMPLOYEES GROUP BY EMPLOYEE, DEPARTMENT)
) GROUP BY EMPLOYEE
and in fact I guess that's what I'll do, but the IBM documentation sure suggests the DISTINCT ought to do the trick. What am I missing?
You haven't specified, but if you use DB2 9.7 LUW, like me, LISTAGG(DISTINCT .. doesn't (yet) work. You have to workaround it by XML functions, e. g.:
with mylist (field1) as
( values 'A','A','B','C','D','A','C'
)
select XMLCAST(
XMLQUERY('string-join(distinct-values($x//row), ", ")'
PASSING XMLGROUP(field1 ORDER BY field1) AS "x"
) AS VARCHAR(200))
from mylist

Divide SELECT value by first entry found

I am fairly inexperienced with SQL, and I have a table that looks like this (simplified version):
ID | Dataset | date | value
I'm trying to divide each value by a baseline, which would be the first entry in the database for that particular dataset.
For example, for dataset1, if the value at 05/05/2018 is 28, and the first value in the database is 4 at 01/01/2018, then I want the result to be 28/4.
thing is that not every dataset was added to the database at the same time, so they have different dates for their baseline. So if dataset1 has its first entry at 01/01/2018, dataset2 might have its first entry at 02/02/2018.
How would I go about this query? I tried a simple div, but it seems like I can only divide by a single number, and not a value-by-value table.
I tried something like this:
SELECT DATE(date) as time, value, dataset / (
SELECT min(DATE(date)) as time, value, dataset FROM table GROUP BY dataset)
FROM table GROUP BY time, dataset
but I think SQL expects the denominator to be a single value in this case, not a table.
Check this out:
SELECT T1.Date
,T1.Value/T2.Value Value
FROM TempTable T1
INNER JOIN TempTable T2
ON T2.Id
=
(SELECT T2.Id
FROM TempTable T2
WHERE T1.Dataset=T2.Dataset
ORDER BY T2.Date
LIMIT 1
)
"I think SQL expects the denominator to be a single value in this case, not a table." You are on the right track, so the sub select needs to return a single value, below is an example:
SELECT
value, (select value from table b where a.dataset = b.dataset and b.dt = (select min(dt) from table c where b.dataset = c.dataset))
FROM
table a
In MySQL 8+, you would simply do:
select t.*,
t.value / first_value(t.value) over (partition by t.dataset order by t.date) as ratio
from t;

SQL Splitting in MySQL without own functions

I have a little problem with some strange strings in one's database table.
I need to split such examples of strings to arrays of INT or separetely to INT looping or sth.
This must be done in 'usual' MySQL (no functions, declares etc - only SELECT statements + built-in-functions like REPLACE(), SUBSTRING())
524;779; 559;; ;559; 411;760;; + others;
Is such intention possible to perform?
If this is a run-once operation to convert your data into a sane format, you could take the idea from this answer and extend it to the maximum number of ids in one string.
Example on SQL Fiddle.
SELECT DISTINCT id, val
FROM (
SELECT id, substring_index(substring_index(`val`,';',-1),';',1) AS val FROM tab
UNION ALL
SELECT id, substring_index(substring_index(`val`,';',-2),';',1) FROM tab
UNION ALL
SELECT id, substring_index(substring_index(`val`,';',-3),';',1) FROM tab
UNION ALL
SELECT id, substring_index(substring_index(`val`,';',-4),';',1) FROM tab
UNION ALL
SELECT id, substring_index(substring_index(`val`,';',-5),';',1) FROM tab
) x
WHERE val <> ''
ORDER BY id