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, '') = ''
Related
I am running a query in which I need the SCORE to have a different output for each row. I am able to do it per execution but I have had no luck with RAND as I get a convert from varchar to int error. I need variable number per execution within a range with no decimals. Is there anyway to do this? Any help is appreciated.
SELECT
'Row_Number^FEED_date^database_id^station_id^Form_Type^FBCS_CLAIM_ID^FBCS_LINE_ID^Pay^SCORE^score_date^reason_code^reason_description'
UNION ALL
SELECT
CAST(ROW_NUMBER() OVER ( ORDER BY ( SELECT 1 ) ) AS VARCHAR(20)) + '^' +
CONVERT(VARCHAR, getdate(), 112)+ '^' +
'FBCSTrans'+ '^' + ---took off the 1 so if problems put it back
stationnumber+ '^' +
case when claimtype = 0 then 'HCFA 1500' else 'UB 1450' end+ '^' +
CAST(Claims.claimid AS VARCHAR(50)) + '^' +
CAST(LineID AS VARCHAR(50)) + '^' +
'Y'+ '^' +
**RAND() * 100000 AS random_number** + '^' +
CONVERT(VARCHAR, getdate(), 112)+ '^' +
'' + '^' + ''
FROM
Claims
JOIN
ClaimLines ON Claims.Claimid = Claimlines.Claimid
JOIN
Facilities ON Claims.FacilityID = Facilities.FacilityID
WHERE
Claims.ClaimId IN (SELECT TOP(100000) ClaimId
FROM CLAIMS
WHERE Claims.RecordStatus = 55 AND facilityid = 40)
USE [DATABASE NAME]
SELECT 'Row_Number^FEED_date^database_id^station_id^Form_Type^FBCS_CLAIM_ID^FBCS_LINE_ID^Pay^SCORE^score_date^reason_code^reason_description'
UNION ALL
SELECT
CAST(ROW_NUMBER() OVER ( ORDER BY ( SELECT 1 ) ) AS VARCHAR(20)) + '^' +
CONVERT(VARCHAR, getdate(), 112)+ '^' +
'DATABASE NAME'+ '^' + ---took off the 1 so if problems put it back
stationnumber+ '^' +
case when claimtype = 0 then 'HCFA 1500' else 'UB 1450' end+ '^' +
CAST(Claims.claimid AS VARCHAR(50)) + '^' +
CAST(LineID AS VARCHAR(50)) + '^' +
'Y'+ '^' +
CAST (FLOOR(RAND(CHECKSUM(NEWID()))*(1000-0+1)+100) As NVARCHAR) + '^' +
CONVERT(VARCHAR, getdate(), 112)+ '^' +
'' + '^' + ''
FROM Claims
JOIN ClaimLines on Claims.Claimid = Claimlines.Claimid
JOIN Facilities ON Claims.FacilityID = Facilities.FacilityID
WHERE Claims.ClaimId IN (SELECT TOP(100000)ClaimId FROM CLAIMS WHERE Claims.RecordStatus = 55 and facilityid=40)
Have a select Statement like
select
SouceField_A
+ 'DeliminiterCharacter'
+ SouceField_A
+ 'DeliminiterCharacter'
+ SourceField_B
+ 'DeliminiterCharacter'
...
Problem is that in real life I do not have a simple Field, but have CASE WHEN ... END. This makes it error prone and difficult to Keep both places up to date when Change is required.
For this I wonder if there is an easy way to put it into variable etc.
Below is part of query to Show
select
ISNULL ( Oracle_Update , 'create' ) + '~' +
#Email + '~' +
#ItemNo + '~' +
'' + '~' +
'D' + '~' +
ISNULL ( Item_Desc_DE , '' ) + '~' +
REPLACE(REPLACE(ISNULL ( Item_Specification_DE , '' ), CHAR(13), ''), CHAR (10), ' $#') + '~' +
ISNULL ( Item_Copy_From, '' ) + '~' +
-- master template
CASE WHEN Oracle_Update like 'update' OR item_copy_from is not NULL
THEN
''
ELSE ISNULL ( Item_Template , 'MAG Assembly' )
END + '~' +
CASE WHEN Oracle_Update like 'update' OR item_copy_from is not NULL
THEN
''
ELSE ISNULL
Just use a nested query:
select
SouceField_A
+ 'DeliminiterCharacter'
+ SouceField_A
+ 'DeliminiterCharacter'
+ SourceField_B
+ 'DeliminiterCharacter'
FROM (
SELECT CASE ... ) AS t
You can used a derived table, where this table is defined in the FROM clause. I've given the long code the column aliases SourceField_A and SourceField_B. The derived table is aliased dT. For clarity, the SELECT clause can use the alias in front of the column name. For example, dT.SourceField_A
SELECT dT.SourceField_A
+ 'DeliminiterCharacter'
+ dT.SourceField_A
+ 'DeliminiterCharacter'
+ dT.SourceField_B
+ 'DeliminiterCharacter'
FROM (
ISNULL ( Oracle_Update , 'create' ) + '~' +
#Email + '~' +
#ItemNo + '~' +
'' + '~' +
'D' + '~' +
ISNULL ( Item_Desc_DE , '' ) + '~' +
REPLACE(REPLACE(ISNULL ( Item_Specification_DE , '' ), CHAR(13), ''), CHAR (10), ' $#') + '~' +
ISNULL ( Item_Copy_From, '' ) + '~' +
-- master template
CASE WHEN Oracle_Update like 'update' OR item_copy_from is not NULL
THEN
''
ELSE ISNULL ( Item_Template , 'MAG Assembly' )
END + '~' +
CASE WHEN Oracle_Update like 'update' OR item_copy_from is not NULL
THEN
''
ELSE ISNULL
...
AS SourceField_A
,...
AS SourceField_B
) AS dT
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 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?
I'm having problems with the below query, working in SQL Server.
SELECT
emp_id= CASE employee_id
WHEN ''
THEN RTRIM(last_name) + '_' + RTRIM(first_name)
+ '_' + RTRIM(gender) + '_'
+ RTRIM(race_ethnicity_code) + '_'
+ RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
+ RTRIM(assignment_code)
ELSE employee_id
END ,
last_name, first_name,
assign_perc,
assignment_num,
CAST((total_salary)AS NUMERIC (18,2))* CAST((assign_perc) AS NUMERIC (18,2)) AS salary,
total_salary
FROM employee
ORDER BY last_name, first_name, district_name
My script is a simple extraction of columns, creating a unique key through case statement for emp_id when its null. The problem im having is when multiplying the assign_perc with the total_Salary when that person has multiple assignments and taking the max salary when that sales person is only listed once. For example - my expected results:
John Smith is only a part time worker having one assignment being listed only one time, so his assign_perc will be less than 1 but I still need the max salary rather than the aggregate total (assign_perc*total_salary). Thank you for your help.
As noted above, this is excessively messy since you'll need to use the CASE statement to determine the virtual employee_id. It would be much simpler if you can either refactor this CASE statement into a udf, or store the result in the table for goodness sake!
To clarify what this is going to do - you want to join the employee table on a table containing counts for each employee. The count table would look like this:
SELECT employee_id, COUNT(*) AS employee_count
FROM employee
GROUP BY employee_id
Joining them together would look like this:
SELECT ...
FROM employee
JOIN (SELECT employee_id, COUNT(*) AS employee_count
FROM employee
GROUP BY employee_id) ec
ON employee.employee_id = ec.employee_id
Your calculated salary would now become:
CASE
WHEN ec.employee_count > 1
THEN CAST((total_salary)AS NUMERIC (18,2))* CAST((assign_perc) AS NUMERIC (18,2))
ELSE total_salary
END AS salary,
And here is the complete query substituting the monstrous CASE statement in place of 'employee_id':
SELECT
CASE employee.employee_id
WHEN ''
THEN RTRIM(last_name) + '_' + RTRIM(first_name)
+ '_' + RTRIM(gender) + '_'
+ RTRIM(race_ethnicity_code) + '_'
+ RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
+ RTRIM(assignment_code)
ELSE employee.employee_id
END AS emp_id,
last_name, first_name,
assign_perc,
assignment_num,
CASE
WHEN ec.employee_count > 1
THEN CAST((total_salary)AS NUMERIC (18,2))* CAST((assign_perc) AS NUMERIC (18,2))
ELSE total_salary
END AS salary,
total_salary
FROM employee
JOIN (SELECT CASE employee.employee_id
WHEN ''
THEN RTRIM(last_name) + '_' + RTRIM(first_name)
+ '_' + RTRIM(gender) + '_'
+ RTRIM(race_ethnicity_code) + '_'
+ RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
+ RTRIM(assignment_code)
ELSE employee.employee_id
END AS employee_id, COUNT(*) employee_count
FROM employee
GROUP BY CASE employee.employee_id
WHEN ''
THEN RTRIM(last_name) + '_' + RTRIM(first_name)
+ '_' + RTRIM(gender) + '_'
+ RTRIM(race_ethnicity_code) + '_'
+ RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
+ RTRIM(assignment_code)
ELSE employee.employee_id
END) ec
ON CASE employee.employee_id
WHEN ''
THEN RTRIM(last_name) + '_' + RTRIM(first_name)
+ '_' + RTRIM(gender) + '_'
+ RTRIM(race_ethnicity_code) + '_'
+ RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
+ RTRIM(assignment_code)
ELSE employee.employee_id
END = ec.employee_id
ORDER BY last_name, first_name, district_name