SQL using CASE with STRING function - sql

I'm trying to write a SQL query that uses CASE and STRING together and getting an error.
This is what I'm trying to work on. Any help is greatly appreciated.
I tried adding in STRING function as well but also does not work.
SELECT Case
when sn.1_code = 1 then 'Attended -- ' ,
sn.mult_1 ,
, 'and' ,
sn.dict_2 ,
' also acted with ' ,
sn.dict_3 ,
'.' ,
when sn.1_code = 3 then 'left because ' ,
sn.mult_2 ,
'.' ,
when sn.dict_1 = 2 then 'Went home' ,
when sn.dict_1 = 24 then 'Canceled' AS 'Attendance'
FROM db.sn

It looks like you're trying to concatenate strings. The actual operator may vary depending on your server software, but the idea would be:
SELECT
Case
when sn.1_code = 1
then 'Attended -- ' + sn.mult_1 + 'and' + sn.dict_2 + ' also acted with ' + sn.dict_3 + '.'
when sn.1_code = 3
then 'left because ' + sn.mult_2 + '.' ,
when sn.dict_1 = 2
then 'Went home' ,
when sn.dict_1 = 24
then 'Canceled'
End AS 'Attendance'
FROM db.sn

As other answers have pointed out, you need to concatenate your string values together. From the very very very little I know of Intersystems Cache SQL (I just looked it up), you will need to use || to concatenate the values (you can also use the CONCAT() function to do this, but it only allows two paramaters):
SELECT Case
when sn.1_code = 1 then 'Attended -- ' ||
sn.mult_1 ||
'and' ||
sn.dict_2 ||
' also acted with ' ||
sn.dict_3 ||
'.'
when sn.1_code = 3 then 'left because ' ||
sn.mult_2 ||
'.'
when sn.dict_1 = 2 then 'Went home'
when sn.dict_1 = 24 then 'Canceled' END AS 'Attendance'
FROM db.sn
You also had some extra commas in there, as well as a missing END at the end of your CASE statement

Intersystems Cache appears to support the two argument concat() function (ala Oracle). It also supports string(). This should do what you want:
SELECT (Case when sn.1_code = 1
then string('Attended -- ', sn.mult_1, 'and', sn.dict_2 , ' also acted with ', sn.dict_3 , '.' )
when sn.1_code = 3
then string('left because ', sn.mult_2 , '.' )
when sn.dict_1 = 2
then 'Went home'
when sn.dict_1 = 24
then 'Canceled'
end) AS 'Attendance'
FROM db.sn;
The case statement also needs an end.

If you're trying to concatenate, as it seems to me, you do it with the + character, and not the comma:
SELECT
Case when sn.1_code = 1 then 'Attended -- ' +
sn.mult_1 +
'and' +
sn.dict_2 +
' also acted with ' +
sn.dict_3 +
'.'
when sn.1_code = 3
then 'left because ' + sn.mult_2 + '.'
when sn.dict_1 = 2 then 'Went home'
when sn.dict_1 = 24 then 'Canceled'
END AS 'Attendance'
FROM db.sn
Without seeing your example with the String function, I don't know what you were trying to do with it.

Related

I'm having an issue with syntax in a Stored SQL Procedure

I'm trying to add three additional columns to a stored procedure (I don't have a lot of experience in stored procedures), the columns are Family ID, Address, and Phone No. Although I've run the query and confirmed the syntax for my select statement is correct, when I add the statement to the stored proc, I receive the following error: Incorrect syntax near 'capPrograms'(this would be line 14). I know this probably has to do with hoe I'm trying to implement my statement in the procedure to update it, but I'm not quite sure what the issues as I've tried several changes with similar or more extensive errors. Any assistance is appreciated, I've included the block of code I'm working with below:
SELECT capCase.Id AS capCase_Id,
capCase.DateApplied AS capCase_DateApplied,
CASE
WHEN ISNUMERIC(#cases.origCaseYear)=1 THEN CAST(origCaseYear + 2004 AS VARCHAR) + ' - ' + CAST(capCase.IdYear + 2004 AS VARCHAR)
WHEN #cases.maxRolloverYear IS NOT NULL THEN CAST(capCase.IdYear + 2004 AS VARCHAR) + ' - ' + CAST(#cases.MaxRolloverYear + 2004 AS VARCHAR)
ELSE CAST(capCase.IdYear + 2004 AS VARCHAR)
END AS capCase_IdYear,
Person.id as Person_id,
Person.LastName + ', ' + Person.FirstName AS PersonPrint_Name,
person.idFamily AS Family_ID, person.homePhone AS Phone_No, (SELECT family.physicalAddress1+ ', ' + family. physicalAddressCity+ ' ' +family. physicalAddressZip) AS Address
FROM Family
LEFT JOIN person ON family.Id = person.idFamily;
capPrograms.Program AS capPrograms_Program,
capStatus.Status AS capStatus_Status,
#lastFollowup.followupDate AS capCaseFollowup_Date,
CASE
WHEN capCase.IdCaseWorker IS NULL THEN 'No Worker Assigned'
ELSE caseWorker.LastName + ', ' + caseWorker.FirstName + ISNULL('<' + caseWorker.EmailWork + '>', '')
END AS capCase_IdCaseWorker,
capcaseDenialReason.reason AS capCase_idDenialReason,
Too long to comment, so I added a bunch of comments in your code. You have, A LOT of issues.
SELECT
capCase.Id AS capCase_Id,
capCase.DateApplied AS capCase_DateApplied,
CASE
--here you are referencing a temp table, which isn't joined below
WHEN ISNUMERIC(#cases.origCaseYear)=1 THEN CAST(origCaseYear + 2004 AS VARCHAR) + ' - ' + CAST(capCase.IdYear + 2004 AS VARCHAR)
WHEN #cases.maxRolloverYear IS NOT NULL THEN CAST(capCase.IdYear + 2004 AS VARCHAR) + ' - ' + CAST(#cases.MaxRolloverYear + 2004 AS VARCHAR)
ELSE CAST(capCase.IdYear + 2004 AS VARCHAR)
END AS capCase_IdYear,
Person.id as Person_id,
Person.LastName + ', ' + Person.FirstName AS PersonPrint_Name,
person.idFamily AS Family_ID,
person.homePhone AS Phone_No,
--this subquery as no from clause... that's an issue... you probably want to remove it completly and replace it with the one below
(SELECT family.physicalAddress1+ ', ' + family. physicalAddressCity+ ' ' +family. physicalAddressZip) AS Address,
--this is likely what you want
family.physicalAddress1 + ', ' + family. physicalAddressCity + ' ' + family. physicalAddressZip AS AddressCorrected
FROM Family
LEFT JOIN person ON
family.Id = person.idFamily; --you have a ; here, which terminates the statement. Everything else below isn't included
--Here you need to join the capPrograms and #lastFollowup table..
--here, you listed some columns, without a table reference. You need to join the table above, and move these columns above the FROM clause
capPrograms.Program AS capPrograms_Program,
capStatus.Status AS capStatus_Status,
#lastFollowup.followupDate AS capCaseFollowup_Date,
CASE
WHEN capCase.IdCaseWorker IS NULL THEN 'No Worker Assigned'
ELSE caseWorker.LastName + ', ' + caseWorker.FirstName + ISNULL('<' + caseWorker.EmailWork + '>', '')
END AS capCase_IdCaseWorker,
capcaseDenialReason.reason AS capCase_idDenialReason,

CASE statement: Inconsistent conversion fail error - varchar to int

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.

Eliminating a space in concatenated values when null

My SELECT statement reads something like this:
SELECT JKLL.LKJJ, LKJF.ASLKD, TRIM (ADDR.UNNBR) || ' ' || TRIM(ADDR.PREDIR) || ' ' ||, TRIM(ADDR.STREET)....
Where UNNBR is the address number and PREDIR is the predirection (NSEW).
When concatenating into the same column, if predir is null, I get two spaces between UNNBR and STREET, obviously.
Can I use a case statement to eliminate this space when PREDIR is null? If so, what would that syntax look like?
I sometimes do something like this for these situations:
(TSQL syntax)
SELECT
CASE WHEN ADDR.UNNBRIS IS NOT NULL THEN ADDR.UNNBR + ' ' ELSE '' END +
CASE WHEN ADDR.PREDIR IS NOT NULL THEN ADDR.PREDIR + ' ' ELSE '' END +
...
This way you only get the space if the field isn't null.
I would use ISNULL
SELECT JKLL.LKJJ, LKJF.ASLKD, TRIM(ADDR.UNNBR) + ISNULL(' ' + TRIM(ADDR.PREDIR),'') ...
A NULL value concatenated to anything yields a NULL. So something like this will work:
WITH ex as
(SELECT 'Pants' as item, null as other, 'George' as name)
SELECT COALESCE(item + ' ', '')
+ COALESCE(other + ' ', '')
+ COALESCE(name + ' ', '')
FROM ex

Added a few lines of code and now query is taking 5x as long to run. Executions plans are almost identical

I have a query that has been in production a long time and takes an average of 4 seconds to run. I added the code below which is a declaration of a table and then an insert into that table. then the select query joins to that and returns 1 field from it in the select statement. Now the query takes up to 25 seconds to run.
DECLARE #tmpStageLoc TABLE
(
LP VARCHAR(20) ,
stgloc VARCHAR(20)
)
INSERT INTO #tmpStageLoc
EXEC dbo.spGetStageLoc #ActLP = #LP;
--Try to get data from DW tables first.
INSERT INTO [COMMON_INFORMATION].[dbo].[ProcTmpData]
( SPID ,
DataSetName ,
IntValue1 , --JRB004
ChValue1 , --JRB001
String1 ,
InsDate
)
SELECT DISTINCT
##SPID ,
#datasetname ,
ls.ToDC ,
col.Cust_No --JRB001
,
REPLACE(#LOADNUM, ' ', '') + --JRB007
'~' + 'N/A'
+ --JRB005 Wave number no longer printed on label
'~' + CASE WHEN la.stage_loc IS NULL THEN ''
ELSE la.stage_loc + '-' + ISNULL(la.misc_info,
'')
END + '~' + fa.OrderControlNo + '~' + col.Cust_No
+ '~' + SUBSTRING(cst.name, 1, 20) + '~'
+ SUBSTRING(cst.name, 21, 5) + '~' + LEFT(cst.address1
+ ', '
+ CASE
WHEN cst.address2 IS NULL
THEN ''
ELSE ( cst.address2
+ ', ' )
END + cst.city
+ ', '
+ cst.state, 45)
+ '~' + ls.StopNO + '~' + ls.LoadNo + '~' + e.first_name
+ ' ' + e.last_name + --JRB009
'~' + --JRB009
CASE WHEN cst.plt_usage IS NULL --JRB009
THEN '' --JRB009
ELSE --JRB009
'# ' + LEFT(cst.plt_usage, 20) --JRB009
END + '~' + ISNULL(STG.STGLOC, '') + '~' --JRB009
,
#RUNDTE
FROM dbo.tblFactAction AS fa
LEFT OUTER JOIN COMMON_INFORMATION.dbo.LoadStop AS ls ON LEFT(fa.OrderControlNo,
8) = ls.ExtOrderNo
AND ls.LatestLoadFlg = 1 --JRB008
LEFT OUTER JOIN dbo.RP_LaneAssign AS la ON ls.LoadNo = la.carrier_move_id
OR ls.ExtOrderNo = la.order_num
LEFT OUTER JOIN dbo.Cust_Order_Lookup AS col ON fa.OrderControlNo = col.Order_Control_no
LEFT OUTER JOIN COMMON_INFORMATION.dbo.Partners AS cst ON col.Cust_No = cst.partner_shipto
LEFT OUTER JOIN COMMON_INFORMATION.dbo.Employee AS e ON fa.EmployeeID = CAST(e.emp_no AS VARCHAR(40))
LEFT OUTER JOIN #tmpStageLoc STG ON fa.actlp = STG.LP
WHERE fa.ActLP = #LOADNUM
AND fa.AssignTypeID IN ( 'PB01', 'PF01' )
I have looked at the execution plans in SQL Sentry Plan Explorer and they look almost identical. I am using the free version of the software. I am at a loss at why the query takes so long to run. just an FYI when I execute the stored procedure that is being called it runs instantly.
Any ideas on how I can figure out why the query now runs for so long?

case and concatenation, sql

Im using a SQL server database and im having a hard time with my case statement. What I'm trying to do is insert a concatenation of attributes into an id field (state_issue_teacher_id) when it equals '' (empty field). The problem is that I have some empty id fields that I need to fill with a unique id that is created by a concatenation of attributes through the case statement.
The empty rows above I need to fill with a concatenation of last_name+first_name+gender+race_ethnicity_code+high_degree_code+position_code+assignment_code.
Here is what I have so far:
SELECT
state_issue_teacher_id,
region_code
+ county_code
+ district_code AS district_code ,
last_name ,
first_name ,
assigned_fte = CASE assign_fte
WHEN '' THEN 0
ELSE CAST(assign_fte AS NUMERIC(18,
2))
END ,
CASE WHEN state_issue_teacher_id = '' THEN
RTRIM([last_name]) + '_' + RTRIM([first_name]) + '_' + RTRIM([gender])
+ '_' + RTRIM([race_ethnicity_code]) + '_' + high_degree_code + '_'
+ position_code + '_' + assignment_code
ELSE state_issue_teacher_id
END,
year_time
FROM dbo.example
When concatenating like that you need to account for two possible problems.
First are all of the fields you are concatenating together varchar (or nvarchar) or are some of them int or numeric? If your datatypes are not varchar or nvarchar, then you need to convert them to use them in a concatentation.
The next possible problem is if one or more of the values can be null. You will need to coalesce any value that could be null with a varchar value (usually a space or empty string for a concatenations although sometimes the value "unknown" works too)) or the concatenation will return null as null concatenated with anything else is null.
SELECT
state_issue_teacher_id,
region_code
+ county_code
+ district_code AS district_code ,
last_name ,
first_name ,
assigned_fte = CASE assign_fte
WHEN '' THEN 0
ELSE CAST(assign_fte AS NUMERIC(18,
2))
END ,
CASE WHEN state_issue_teacher_id = '' THEN
RTRIM(coalesce([last_name],'ValueYouUseInsteadOfNull')) + '_' +
RTRIM(coalesce([first_name],'ValueYouUseInsteadOfNull')) + '_' +
RTRIM(coalesce([gender],'ValueYouUseInsteadOfNull')) + '_' +
RTRIM(coalesce([race_ethnicity_code],'ValueYouUseInsteadOfNull')) + '_' +
coalesce(high_degree_code,'ValueYouUseInsteadOfNull') + '_' +
coalesce(position_code,'ValueYouUseInsteadOfNull') + '_' +
coalesce(assignment_code,'ValueYouUseInsteadOfNull')
ELSE state_issue_teacher_id
END,
year_time
FROM dbo.example
Odds are, you have null in some of those fields.
Give this query a try.
Thank you for everyone that answered the question. I got it to work with the below query.
SELECT
state_issue_teacher_id,
region_code
+ county_code
+ district_code AS district_code ,
last_name ,
first_name ,
gender,
race_ethnicity_code,
high_degree_code,
position_code,
assignment_code,
assigned_fte = CASE assign_fte
WHEN '' THEN 0
ELSE CAST(assign_fte AS NUMERIC(18,
2))
END ,
state_issue_teacher_id =
CASE state_issue_teacher_id WHEN '' THEN
RTRIM([last_name]) + '_' + RTRIM([first_name]) + '_' + RTRIM([gender])
+ '_' + RTRIM([race_ethnicity_code]) + '_' + high_degree_code + '_'
+ position_code + '_' + assignment_code
ELSE state_issue_teacher_id
END,
year_time
FROM dbo.example
How about?:
update example
set state_issue_teacher_id =
RTRIM([last_name]) + '_' + RTRIM([first_name]) + '_' + RTRIM([gender])
+ '_' + RTRIM([race_ethnicity_code]) + '_' + high_degree_code + '_'
+ position_code + '_' + assignment_code
WHERE isnull(state_issue_teacher_id, '') = ''