Conditionally count based on other field data in SSRS Report - sql-server

I am working SSRS report, I have a field named as Details and I would like to get the count of other field SerialNumber.
So in short I want to get the total count of SerialNumber which has no Details.
I tried below but not working. It always give the total count count without considering blank Details
=CStr(COUNT(IIF(Not(IsNothing(Fields!Details.Value)),Fields!SerialNumber.Value,0)))
How can I achieve this by expression? Please help.

Issue was with my data. In dataset I was fetching rows based on Isnull() like below
SELECT CASE
WHEN 'Y'='Y' THEN ISNULL(Code ,'') + ' ' + ISNULL(Description ,'')
ELSE CASE
WHEN ISNULL(Code ,'')='' THEN ISNULL(RefCharge ,'')
+' '+ISNULL(RefDescription ,'')
ELSE ISNULL(Code ,'')+' '+ISNULL(Description ,'')
END
END AS Details
So it was showing (3 blank spaces) and my expression was.
=COUNT(IIF(Fields!Details.Value<>"",Fields!Number.Value,Nothing))
Finally I tried below, now it's working fine now.
=COUNT(IIF(Trim(Fields!Details.Value)<>"",Fields!Number.Value,Nothing))
Note: So I have noted that whenever we need to check such kind of conditions we must have to use Trim()

Related

Get the specified input parameter from stored procedure

I want to get all the related information from database. For example I have a summary column which contains data like "A01.1 | Foodland Inbound QIP Details and Pre Unloading" and I want to pass only "A01" in input parameter and get all the data related to "A01"
select * from TableName where summary_column like 'A01%';
Based on the code in your comment, the where clause will only find a summary that is the equal to A01.2 e.g:
TaskMaster.Summary =#summary
You want to use LIKE and a wild card:
WHERE TaskMaster.Summary LIKE '''' + #summary + '%' + ''''
The above will find everything that starts with A01.2, so if you want to find all with A01, pass #summary as A01

SQL XML parsing using a attribute value supplied by another field in the same row

Context: I'm scraping some XML form descriptions from a Web Services table in hopes of using that name to identify what the user has inputted as response. Since this description changes for each step (row) of the process and each product I want something that can evaluate dynamically.
What I tried: The following was quite useful but it returns a dynamic attribute query result in it's own field ans using a coalesce to reduce the results as one field would lead to it's own complications: Get values from XML tags with dynamically specified data fields
Current Attempt:
I'm using the following code to generate the attribute name that I will use in the next step to query the attribute's value:
case when left([Return], 5) = '<?xml'
then lower(cast([Return] as xml).value('(/response/form/*/#name)[1]','varchar(30)'))
else ''
end as [FormRequest]
And as part of step 2 I have used the STUFF function to try and make the row-level query possible
case when len(FormRequest)>0
then stuff( ',' + 'cast([tmpFormResponse] as xml).value(''(/wrapper/#' + [FormRequest] + ')[1]'',''varchar(max)'')', 1, 1, '')
else ''
end as [FormResponse]
Instead of seeing 1 returned as my FormReponse feild value for the submit attribute (please see in yellow below) it's returning the query text -- cast([tmpFormResponse] as xml).value('(/wrapper/#submit)1','varchar(max)') -- instead (that which should be queried).
How should I action the value method so that I can dynamically strip out the response per row of XML data in tmpFormResponse based on the field value in the FormRequest field?
Thanx
You can check this out:
DECLARE #xml XML=
N'<root>
<SomeAttributes a="a" b="b" c="c"/>
<SomeAttributes a="aa" b="bb" c="cc"/>
</root>';
DECLARE #localName NVARCHAR(100)='b';
SELECT sa.value(N'(./#*[local-name()=sql:variable("#localName")])[1]','nvarchar(max)')
FROM #xml.nodes(N'/root/SomeAttributes') AS A(sa)
Ended up hacking up a solution to the problem by using PATINDEX and CHARINDEX to look for the value in the [FormRequest] field in the he tmpFormResponse field.

Concat the values in a string with SQL Server

I want to select a list of items and part numbers for for each item as a string:
SELECT top 100 *
FROM ii
OUTER APPLY
(SELECT def, ( ipr.part_number + ',') as prt
FROM ipr
WHERE ii.item_id = ipr.item_id
FOR XML PATH('') ) PN
The error is:
[Error Code: 8155, SQL State: S0002] No column name was specified for
column 1 of 'PN'.
How can I fix this?
I think that your whole OUTER APPLY statement generates one XML for both default_part_number and concatenated string, which(the whole XML) doesn't have a name.
What you could try to do would be adding alias like this AS PN(TestThis).
However, I don't think that you're expecting result you're going to get. It would better if you'd give us some example data and expected output. It will be easier for us to solve your problem in that case.
The combination of XML and STUFF is funny but perfectly fitting to your needs.
First you concat your strings with the ', ' in front, then you must return your XML with ", TPYE). You must read the result with ".value()" and use STUFF to replace the first ', '.
You'll find a lot of exampels in the net...

Intra-SELECT variables?

Would it be possible to alias an expression returned by a SELECT statement in order to refer to it in other parts of this same SELECT as if it would be a column among others ?
A kind of "temporary variable" whose scope would be limited to the SELECT statement, a little bit like the WITH clause before a SELECT to use a temporary named recorset.
A naive sample of what I'd like to achieve :
SELECT
FIRSTNAME + ' ' + NAME AS FULLNAME,
CASE WHEN LEN(FULLNAME)>3 THEN 1 ELSE 0 END AS ISCORRECT
FROM USERS
where FULLNAME could be used to determine the subsequent output field ISCORRECT, though not being a real column of the table USERS... instead of this laboured error-prone (but working) copy/paste :
SELECT
FIRSTNAME + ' ' + NAME AS FULLNAME,
CASE WHEN LEN(FIRSTNAME + ' ' + NAME)>3 THEN 1 ELSE 0 END AS ISCORRECT
FROM USERS
This sample well describes what I want, but I can easily imagine similar needs where FULLNAME might also be used in other parts of the SELECT statement : in a JOIN, in the WHERE, in a GROUP BY, ORDER BY, etc.
PS : I use SQL Server 2005 but would be also interested in any 2008-specific answer.
Thanks a lot ! :-)
Edit :
In spite of my high respect towards those of you proposing to use a side- or inner-query, I don't feel at ease with such possibilities. My sample really is a naive one. The true queries are rather with 30 output fields including complex expressions (including calls to CLR functions), 15 inner/left outer joins, and 20 additionnal where criteria. I suspect I had rather not multiplying to many indirections towards co-queries if I can avoid it.
I believe you would have to put it in an inner query, and then be able to refer to it outside of the query.
Simplest example based on yours:
select a.fullname, case when len(a.fullname) > 3 then 1
else 0 end as incorrect
from (select firstname + ' ' + name as fullname
from users) a
Example with a CTE
;with names (FULLNAME) as (
SELECT FIRSTNAME + ' ' + NAME
FROM USERS
) select
FULLNAME,
CASE WHEN LEN(FULLNAME) > 3 THEN 1 ELSE 0 END AS ISCORRECT
FROM names
You can use cross apply to concatenate strings or do calculations etc.. that involves just the current row.
select T.fullname,
case when len(T.fullname) > 3
then 1
else 0
end iscorrect
from users as U
cross apply
(select U.firstname+' '+U.name) as T(fullname)
order by T.fullname
Though not very satisfied with it, I choose (temporarily ?) a third option : I avoid co-queries and copy/pasting my complex hard-to-read expression (here symbolized by the simple one aliased as FULLNAME) by embeddind it in a scalar function... which is therefore called several times in different parts of my SELECT.
SELECT
dbo.GetFULLNAME(FIRSTNAME,NAME) AS FULLNAME,
CASE WHEN LEN(dbo.GetFULLNAME(FIRSTNAME,NAME))>3 THEN 1 ELSE 0 END AS ISCORRECT
FROM USERS
What do you think of it ?
(I precise that though more complex and unreadable than in my OP, the real expression remains a "simple" matter of string manipulation using several input fields, and doesn't involve any sub-querying or anything like that).

SQL Server : LENGTH() inside of REPLICATE()

I have a SQL Server table with the columns Lvl and Title. I need to insert a "-" in front of the title for every character in the Lvl field.
As an example: If Lvl = 111 the title should become --- My Title.
I can only edit the following SQL string. There is no possibility to create other functions or likewise.
SELECT REPLICATE('_', { fn LENGTH(Lvl) }) + ' ' + Title AS Title
FROM Documents
My problem is, that the LENGTH() function doesn't work inside the REPLICATE() function. Does anybody know why or how to solve this problem?
Thank you.
Try this:
SELECT REPLACE(Lvl, '1', '-') + ' ' + Title as Title
FROM Documents
Simply take the Lvl column, and replace all instances of 1 with whatever character you want, then concatenate Title to the end of the result.
Try this. It works fine for me -
select REPLICATE('-',LEN(Lvl)) + ' ' + Title as title from documents

Resources