I have an sql table that looks like the following
p1 c1 c2 c3 c4 c5 c6 c7
A B C D E F NULL NULL
A B C NULL NULL NULL NULL NULL
A B NULL NULL NULL NULL NULL NULL
A NULL NULL NULL NULL NULL NULL NULL
i need a select sql query with 1 column and the output to look like
Result
A > B > C > D > E > F
A > B > C
A
i tried nested select case however i am getting only nulls
select
case when x.p1 IS not NULL then(
x.p1 + case when x.c1 IS not NULL then(
' > '+ x.c1 + case when x.c2 IS not NULL then(
' > '+ x.c2 + case when x.c3 IS not NULL then(
' > '+ x.c3 + case when x.c4 IS not NULL then(
' > '+ x.c4 + case when x.c5 IS not NULL then(
' > '+ x.c5 + case when x.c6 IS not NULL then(
' > '+ x.c6 + case when x.c7 IS not NULL then(
' > '+ x.c7 )end )end )end )end )end )end )end) end as tree
from mytable
is there a better way to get the result i want?
what is wrong with my select case?
Based on the fact that in TSQL 'a string' + null equals null, you can simplify the query to this:
select
p1
+ isnull(('>' + c1), '')
+ isnull(('>' + c2), '')
+ isnull(('>' + c3), '')
+ isnull(('>' + c4), '')
+ isnull(('>' + c5), '')
+ isnull(('>' + c6), '')
+ isnull(('>' + c7), '')
from mytable
SQLFiddle link: http://www.sqlfiddle.com/#!3/02b05/8
what is wrong with my select case?
You are using the table alias x which appears to not be defined anywhere.
I made your query work in two steps:
define the x table alias. For that, simply write mytable x at the end instead of just mytable
after the above fix, it'll still return null, because the case statements only have one branch and when the condition is not met they still return null. To fix that, replace every end with else '' end (to return an empty string rather than a null)
Here's your version working: http://www.sqlfiddle.com/#!3/02b05/11
Related
i have written a SELECT Query on SQL SERVER 2014 . I have got the desired output . but an apostrophe symbol(') appearing on 'TaskAction' field data(at the end of each data). here it is my script:
SELECT
WOtask.PK,
WOPK,
TaskNo,
TaskAction =
CASE
WHEN WOTask.AssetPK IS NOT NULL THEN '<b>' + Asset.AssetName + ' [' + Asset.AssetID + ']</b> ' + CASE
WHEN Asset.Vicinity IS NOT NULL AND
Asset.Vicinity <> '''' THEN RTRIM(Asset.Vicinity) + ': '
ELSE ''''
END + WOtask.TaskAction + CASE
WHEN CONVERT(varchar, ValueLow) IS NOT NULL AND
CONVERT(varchar, ValueHi) IS NOT NULL AND
Spec = 1 THEN ' (Range: '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueLow,0))) + '' - '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueHi,0))) + )'
ELSE ''''
END
ELSE WOtask.TaskAction + CASE
WHEN CONVERT(varchar, ValueLow) IS NOT NULL AND
CONVERT(varchar, ValueHi) IS NOT NULL AND
Spec = 1 THEN ' (Range: '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueLow,0))) + '' - '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueHi,0))) + )'
ELSE ''''
END
END,
Rate,
Measurement,
Initials,
Fail,
Complete,
Header,
LineStyle,
WOtask.Comments,
WOtask.NotApplicable,
WOTask.Photo1,
WOTask.Photo2
FROM WOtask WITH (NOLOCK)
LEFT OUTER JOIN Asset WITH (NOLOCK)
ON Asset.AssetPK = WOTask.AssetPK
LEFT OUTER JOIN AssetSpecification
ON AssetSpecification.PK = WOTask.AssetSpecificationPK
WHERE (WOPK IN (SELECT
WOPK
FROM WO WITH (NOLOCK)
LEFT OUTER JOIN Asset WITH (NOLOCK)
ON Asset.AssetPK = WO.AssetPK
LEFT OUTER JOIN AssetHierarchy WITH (NOLOCK)
ON AssetHierarchy.AssetPK = WO.AssetPK
WHERE WO.WOPK = 10109)
)
ORDER BY WOPK, TaskNo
now please check my output and error
please help to solve this issue. Thanks in Advance.
As noted in comments, use ELSE '' instead of ELSE ''''. The reason is that within a pair of single quotes, then '' tells SQL to escape a single quote into your output.
For instance, to show the output User's, you would need SELECT 'User''s'.
SELECT
CASE
WHEN Employees.first_name IS NULL
OR Employees.first_name = 'x' THEN Employees.last_name
WHEN Employees.credentials IS NULL THEN Employees.last_name + ', ' + Employees.first_name
ELSE Employees.last_name + ', ' + Employees.first_name + ' - ' + Employees.credentials
END,
Employees.num3,
Employees.address1 + ' ' + Employees.city + ', ' + Employees.state + ' ' + Employees.zip,
Employees.work_phone,
CASE
WHEN Clients.age <= 18 THEN 'Youth'
ELSE 'Adult'
END,
Clients.client_id,
Clients.last_name + ', ' + Clients.first_name,
ClientVisit.cptcode,
ClientVisit.visittype,
ClientVisit.rev_timeout,
ClientVisit.timein,
ClientVisit.duration,
SUM(CASE
WHEN ClientVisit.cptcode = 90791 THEN 200
WHEN ClientVisit.comb_units = 1 THEN 85.67
ELSE ClientVisit.comb_units * 21.4175
END),
DATEDIFF(d, ClientVisit.rev_timeout, ClientVisit.signature_datetime)
FROM dbo.ClientVisit
INNER JOIN dbo.Employees
ON (
ClientVisit.by_emp_id = Employees.emp_id
)
INNER JOIN dbo.Programs
ON (
ClientVisit.program_id = Programs.program_id
)
INNER JOIN dbo.Clients
ON (
Clients.client_id = ClientVisit.client_id
)
WHERE (
ClientVisit.rev_timeout BETWEEN '20160401 11:40:00.000' AND '20160415 11:40:16.000'
AND Programs.program_desc IN ('Off Panel')
AND ClientVisit.non_billable = 0
AND ClientVisit.cptcode NOT IN ('00000', '0124', '100', '1001', '101', '102', '103', '80100', '9079', '99999')
AND Employees.num3 IS NOT NULL
)
GROUP BY
CASE
WHEN Clients.age <= 18 THEN 'Youth'
ELSE 'Adult'
END,
CASE
WHEN Employees.first_name IS NULL
OR Employees.first_name = 'x' THEN Employees.last_name
WHEN Employees.credentials IS NULL THEN Employees.last_name + ', ' + Employees.first_name
ELSE Employees.last_name + ', ' + Employees.first_name + ' - ' + Employees.credentials
END,
DATEDIFF(d, ClientVisit.rev_timeout, ClientVisit.signature_datetime),
ClientVisit.cptcode,
Clients.last_name + ', ' + Clients.first_name,
Clients.client_id,
Employees.address1 + ' ' + Employees.city + ', ' + Employees.state + ' ' + Employees.zip,
Employees.work_phone,
ClientVisit.duration,
ClientVisit.visittype,
ClientVisit.rev_timeout,
ClientVisit.timein,
Employees.num3
Gives me the Error:
Conversion failed when converting the varchar value 'H2019' to data
type int.
I'm unable to locate specifically where this conversion is taking place and what could be a possible fix.
EDIT: Located problem in cptcode column which has alphanumeric entries. However, changing date ranges in WHERE clause gives results for some dates and not for others.
when you use
"ClientVisit"."cptcode" = 90791
the data type of 90791 will be integer. If you replace it with
"ClientVisit"."cptcode" = '90791'
both sides of the equation will be characters. You can also do something like:
"ClientVisit"."cptcode" = CAST(90791 AS VARCHAR(20))
The reasons for your problem is that SQL Server will do an implicit conversion. In this case to integer as Integer has a higher Data Type Precedence than (n)(var)char data types.
Of course I do not know your data but I guess there are data ranges where there is only numeric values for cptcode. So your code will work for them but not if you hit something like e.g. H006
Hope that helps ;-)
Comment out all the colums in the select segment and start ucommenting them one by one while executing the select each time. When you uncomment the problematic line, you'll find the source of the error.
BTW: I'm guessing the problem is in "ClientVisit"."cptcode" = 90791.
I am trying to run reporting services with below SQL query
select ca.callingpartynumber, ca.originalcalledpartynumber, case
when calledpartylastname is not null then ca.calledpartylastname + ',' + calledpartyfirstname
else p1.name end,
p1.location, p1.dept, p1.title,
case
when callingpartylastname is not null then ca.callingpartylastname + ',' + callingpartyfirstname
else p3.name end
from calldata.calldetailreport ca
join ps_bc_peoplesource_base p1 on ca.originalcalledpartynumber = replace(p1.bc_int_phone, '-', '')
left outer join ps_bc_peoplesource_base p3 on ca.callingpartynumber = replace(p1.bc_int_phone, '-', '')
where originalcalledpartynumber in (select replace(bc_int_phone, '-', '') internal_modified from ps_bc_peoplesource_base where bc_lan_id = 'f7c')
--and datetimedisconnect between #startdate and #enddate --1221
I get this error-
“An item with the same key has already been added.”
You are missing Column Alias for Two Case Statement in Your SELECT query. As SSRS uses only the column name as the key, not table + column, so it was choking.
Refer Here And Here And Here also
SELECT ca.callingpartynumber, ca.originalcalledpartynumber,
CASE WHEN calledpartylastname IS NOT NULL
THEN ca.calledpartylastname + ',' + calledpartyfirstname
ELSE p1.name END AS calledpartylastname,
p1.location,
p1.dept,
p1.title,
CASE WHEN callingpartylastname IS NOT NULL
THEN ca.callingpartylastname + ',' + callingpartyfirstname
ELSE p3.name END AS callingpartylastname
...
...
I combine two column value with ',' using below query.
SELECT
RTRIM(LTRIM(REPLACE(
IsNull(tbl1 .Reason,'') + ',' + IsNull(tbl2.OtherReason,''),',' ,'')))
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
Now issue is that it remove all ',' using above query and I want to just remove last and first ','.
I have combine two column. Now
if tbl1 .Reason is null then it display output as " ,tbl2.OtherReason " and if tbl2.OtherReason is null the output is "tbl1 .Reason,"
Before above query, I also try with below query:
SELECT
IsNull(tbl1.Reason,'') + ',' + IsNull(tbl2.OtherReason,'')
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
Thanks,
HItesh
You can use a case in the middle to check if the values are null or not.
declare #a nvarchar(5)
,#b nvarchar(5)
set #a = 'abc'
set #b = null--'123'
select isnull(#a, '') + case when #a is not null and #b is not null then ',' else '' end + isnull(#b, '')
Try this:
SELECT
CASE
WHEN tbl1.Reason IS NULL
THEN
CASE
WHEN tbl2.Reason IS NULL
THEN ''
ELSE LTRIM(RTRIM(tb2.Reason))
END
ELSE tbl1.Reason +
CASE
WHEN tbl2.Reason IS NULL
THEN ''
ELSE ',' + LTRIM(RTRIM(tb2.Reason))
END
END
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
You can concatenate a comma to the first value in case that second value is not null :
SELECT
IsNull(tbl1.Reason + case when tbl2.OtherReason is null then '' else ',' end, '') +
IsNull(tbl2.OtherReason,'')
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
So FIELD2 can return 2 groups of fields concatenated as a single result depending on the value of Mycondition.
My problem is only when Mycondition = 1
If MyCondition = 1 then I need to concatenate INT_FIELD_ONE + 'A' + INT_FIELD_TWO.
The concatenation is not the problem.
The problem is if INT_FIELD_ONE (is null) + 'A' + INT_FIELD_TWO (is null), then I have to return nothing.
My Replace command would work if both fields ONE and TWO are null. But if only 1 is NULL and the other is not the "A" gets deleted any way. The A needs to remain if 1 field is not null.
For Example:
NULL + 'A' + NULL = Nothing
NULL + 'A' + xxxx = Axxxx
xxxx + 'A' + NULL = xxxxA
Therefore I need to make a TSQL replace with a length constraint of result > 1
Any Ideas?
SELECT XXX,
CASE --Case Statement to Return Field2
WHEN MyCondition = 1 THEN
--Constraint on the Replace Starts Here
REPLACE(
Isnull(CAST(INT_FIELD_ONE AS VARCHAR), '') + 'A' +
Isnull(CAST(INT_FIELD_TWO AS
VARCHAR), '')
,'A','')
ELSE
REPLACE(
Coalesce(REPLACE(INT_FIELD_THREE, '', '-'), Isnull(INT_FIELD_THREE, '-'), INT_FIELD_THREE) +
' / ' + Coalesce(REPLACE(INT_FIELD_FOUR, '', '-'),
Isnull(INT_FIELD_FOUR, '-'), INT_FIELD_FOUR) + ' ', '- / - ',
'')
END
AS FIELD2
FROM TABLEX
how about this?
CASE WHEN MyCondition = 1 AND (INT_FIELD_ONE IS NOT NULL OR INT_FIELD_TWO IS NOT NULL) THEN concat..
WHEN MyCondition = 1 THEN NULL -- at that point we know that both are null
ELSE ... END
Notice that now you don't need the REPLACE function when you are doing the concat because you know for sure that one of your fields is not null
…
WHEN MyCondition = 1 THEN
ISNULL(
NULLIF(
ISNULL(CAST(int1 AS VARCHAR), '') + 'A' + ISNULL(CAST(int2 AS VARCHAR), ''),
'A'
),
''
)
…
When both int1 and int2 are NULL, the result of the concatenation will be A. NULLIF() will return NULL if the expression returns A, otherwise it will return the result of the expression. The outer ISNULL() will transform NULL into the empty string or return whatever non-NULL value its first argument has got.