SSRS CountRows of a specific Field containing a specific Value - sql

I am building an SSRS report. I have a DataSet that contains several Fields, one of which is Doc_Type. Doc_Type can contain several values, one of which is 'Shipment'.
In my report, I want to count the number of Doc_Types that are equal to 'Shipment'. This is what I am using, and it is not working:
=CountRows(Fields!Doc_Type.Value = "Shipments")
The error I get is: "The Value expression for the textrun 'Doc_Type.Paragraphs[0].TextRuns[0]' has a scope parameter that is not valid for an aggregate function. The scope parameter must be set to a string constant that is equal to either the name of a containing group, the name of a containing data region, or the name of a dataset.

You need to use an IIF to evaluate your fields and SUM the results. If your expression is in a table, you could use this:
=SUM(IIF(Fields!Doc_Type.Value = "Shipments", 1, 0))

There are many ways to achieve this.
Method 1
You can set up your expression something like this
=SUM(IIf(Fields!Doc_Type.Value = "Shipments", 1, 0), "YourDataSetName")
Remember SSRS is case sensitive so put your dataset name and Field names correctly.
Method 2
I prefer handling it in SQL as I want to keep the business logic out of RDLs.
You can use window functions to get the shipment count.
Also notice in the case of count I haven't added ELSE 0 condition. Because that will give wrong results. Count doesn't care what is the value inside it. It just counts all Non Null values. ELSE NULL will work.
SELECT Column1, Column2, Column3,
SUM(CASE WHEN Doc_Type = 'Shipments' THEN 1 ELSE 0 END) OVER() ShipmentCount_UsingSum
COUNT(CASE WHEN Doc_Type = 'Shipments' THEN 1 END) OVER() ShipmentCount_UsingCount
FROM myTable
JOIN....
WHERE .....
Now you can use this field in the report.

Related

SQLite split column on another column's value

I have a database in which multiple variables appear as consecutive rows (shown below, variables differentiated by their tags). As a result, their values appear as consecutive rows in the 'value' column.
Existing table:
For data analysis, I need to split each variable's value into separate columns, as illustrated below.
The SQLite query is listed below. I have tried using GROUP BY tag and averaging the values, but the result becomes too granular to be useful.
Advice would be much appreciated!
SELECT
tag
,time
,value
FROM
[archive]..[interp]
WHERE
tag
IN
( 'flow1.Val'
, 'flow2.Val'
, 'density1.Val'
, 'density2.Val'
)
AND
time
BETWEEN
't-1d' and 't'
AND
timestep = '1h'
You can use conditional aggregation:
select time,
max(case when tag = 'flow1.Val' then value end) as flow1_val,
max(case when tag = 'flow2.Val' then value end) as flow2_val,
max(case when tag = 'density1.Val' then value end) as density1_val,
max(case when tag = 'density2.Val' then value end) as density2_val
from [archive]..[interp]
group by time
Depending on your actual requirement, you might want to use another aggregate function than max(), it you have more than one row for a given time/tag tuple.

ORA-00909: invalid number of arguments when using NVL

I have a column that gets the specific amount which has a condition like below.
I tried this one to get his specific value but I getting a multiple rows which it should be single row.
select distinct
(case
when aila.line_type_lookup_code = 'ITEM' and aila.tax_classification_code = 'VAT12 SERVICES' then to_char(aila.assessable_value) else '0'
end) as taxable_lines
from
ap_invoice_lines_all aila
where
aila.invoice_id = '31004'
then I tried this one to replace a null values.
select distinct
(case
when aila.line_type_lookup_code = 'ITEM' and aila.tax_classification_code = 'VAT12 SERVICES' then nvl(to_char(aila.assessable_value,0)) end) as taxable_lines
from
ap_invoice_lines_all aila
where
aila.invoice_id = '31004'
For example I have a table named ap_invoice_lines_all that has a columns name
line_type_lookup_code string
tax_classification_code string
assessable_value double
then the expected output I want based on the query I tried above is
taxable lines
1300
but the one I get is
taxable lines
0
1300
How do I remove the 0 in the result?
Thanks!
First off, you are using to_char wrong. This function should only have a single argument in this context:
nvl(to_char(aila.assessable_value,0))
should be
nvl(to_char(aila.assessable_value),0)
I would recommend against using a case expression like this in such a simple query to improve readability. Case expressions are great tools, but typically decrease the query readability. And in this particular instance, you don't really need an IF..THEN..ELSE function (which is the reason to use case expressions).
Secondly, are you sure there is only record where aila.invoice_id = '31004'? The query will only return two rows if there are actually two rows in the table where that clause is true. In this case it finds one row where assessable_value is null and one where it isn't.
In any case, to remove the zero (or in this case a null value) from the resultset, you can simply do this:
select distinct aila.assessable_value as taxable_lines
from ap_invoice_lines_all aila
where aila.invoice_id = '31004'
and aila.line_type_lookup_code = 'ITEM' -- Originally a condition in the case statement
and aila.tax_classification_code = 'VAT12 SERVICES' -- Originally a condition in the case statement
and aila.assessable_value is not null; -- Removes any null values from the result
Or if you want null values to be replaced by a zero;
select distinct nvl(aila.assessable_value, 0) as taxable_lines
from ap_invoice_lines_all aila
where aila.invoice_id = '31004'
and aila.line_type_lookup_code = 'ITEM' -- Originally a condition in the case statement
and aila.tax_classification_code = 'VAT12 SERVICES' -- Originally a condition in the case statement
Note that the distinct clause will cause all rows where assessable_value to be grouped into a single row if multiple rows are a possibility. Remove the distinct clause if you want all rows where assessable_value is null to show in the result as 0.
Lastly, you might want to think about implementing a primary key (if the table doesn't have one) or unique index on invoice_id, if there shouldn't ever be duplicate ids. And it's simply good practice to do so for ID columns which are used often in queries and should be unique.

Conditional COUNT within CASE statement

Table 1, is a list of clients, what membership they have, what service they used, and the date the service was used
Table 2, is just table 1 grouped by month and membership type, then a count of the service sessions
What I am trying to do is count membership sessions only by particular service types. This is what I have so far, it returns an error saying 'Service_Type' is not in an aggregate function or group by clause, when I put 'Service_Type' in a group by, the query has no errors but the SESSIONS column is all NULL.
SELECT
DATEFROMPARTS(YEAR(t1.Date),MONTH(t1.Date),1)AS 'Draft_Date',
Membership,
CASE
WHEN Membership = 5 AND Service_Type = 'A' THEN COUNT(*)
WHEN Membership = 2 AND Service_Type IN ('J','C')
END AS'SESSIONS'
FROM Table1 t1
GROUP BY DATEFROMPARTS(YEAR(t1.Date),MONTH(t1.Date),1),Membership
The case statement will include all memberships and service types but I think this is enough for my example. Any help would be greatly appreciated! I've been on this for days.
Table 1
Table 2
You were nearly there! I've made a few changes:
SELECT
DATEFROMPARTS(YEAR(t1.Date), MONTH(t1.Date),1) AS Draft_Date,
Membership,
COUNT(CASE WHEN t1.Membership = 5 AND t1.Service_Type = 'A' THEN 1 END) as m5stA,
COUNT(CASE WHEN t1.Membership = 2 AND t1.Service_Type IN ('J','C') THEN 1 END) as m2stJC
FROM Table1 t1
GROUP BY YEAR(t1.Date), MONTH(t1.Date), Membership
Changes:
Avoid using apostrophes to alias column names, use ascii standard " double quotes if you must
When doing a conditional count, put the count outside the CASE WHEN, and have the case when return something (any non null thing will be fine - i used 1, but it could also have been 'x' etc) when the condition is met. Don't put an ELSE - CASE WHEN will return null if there is no ELSE and the condition is not met, and nulls don't COUNT (you could also write ELSE NULL, though it's redundant)
Qualify all your column names, always - this helps keep the query working when more tables are added in future, or even if new columns with the same names are added to existing tables
You forgot a THEN in the second WHEN
You don't necessarily need to GROUP BY the output of DATEFROMPARTS. When a deterministic function is used (always produces the same output from the same inputs) the db is smart enough to know that grouping on the inputs is also fine
Your example data didn't contain any data that would make the COUNT count 1+ by the way, but I'm sure you will have other conditional counts that work out (it just made it harder to test)
use sum
SELECT DATEFROMPARTS(YEAR(t1.Date),MONTH(t1.Date),1) AS Draft_Date , Membership,
sum(CASE WHEN Membership = 5 AND Service_Type = 'A' THEN 1 else 0 end),
sum(case WHEN Membership = 2 AND Service_Type IN ('J','C') then 1 else 0 end)
FROM Table1 t1 group by DATEFROMPARTS(YEAR(t1.Date),MONTH(t1.Date),1)

SSRS grouping chart by parameter

I have problem with grouping by parameter in my chart.
Let's assume query that gives data like below:
I would like to Group category in the cart based on parameter.
Parameter has value City or Country but it can be also different (no possibility to define constant list)
On the chart I should see (based on parameter):
Parameter: City
Parameter: Country
Is there any possibility to do it in SSRS?
Assuming your parameter has values of 0 and 1 where 0=Country and 1=City....
You just need to set the following items
The cell to be displayed ( in column 1 in your example)
The Group On expression of your row group
The Sort by expression of your row group
to the same expression, something like this...
=IIF(Parameters!groupColumn.Value =0, Fields!country.Value, Fields!city.Value)
Its the exact same expression in all three places.
If you can't get this working, let me know and I'll post an example but it's pretty simple.
You can do use an expression for group by:
select (case when parameter = 'City' then city
when parameter = 'Country' then country
end) as which,
sum(value)
from t
group by (case when parameter = 'City' then city
when parameter = 'Country' then country
end);
That said, I think you should have separate queries in SSRS for the different values. Such parameterized queries are harder to optimize and harder to maintain.

Return NULL instead of 0 when using COUNT(column) SQL Server

I have query which running fine and its doing two types of work, COUNT and SUM.
Something like
select
id,
Count (contracts) as countcontracts,
count(something1),
count(something1),
count(something1),
sum(cost) as sumCost
from
table
group by
id
My problem is: if there is no contract for a given ID, it will return 0 for COUNT and Null for SUM. I want to see null instead of 0
I was thinking about case when Count (contracts) = 0 then null else Count (contracts) end but I don't want to do it this way because I have more than 12 count positions in query and its prepossessing big amount of records so I think it may slow down query performance.
Is there any other ways to replace 0 with NULL?
Try this:
select NULLIF ( Count(something) , 0)
Here are three methods:
1. (case when count(contracts) > 0 then count(contracts) end) as countcontracts
2. sum(case when contracts is not null then 1 end) as countcontracts
3. nullif(count(contracts), 0)
All three of these require writing more complicated expressions. However, this really isn't that difficult. Just copy the line multiple times, and change the name of the variable on each one. Or, take the current query, put it into a spreadsheet and use spreadsheet functions to make the transformation. Then copy the function down. (Spreadsheets are really good code generators for repeated lines of code.)