SQL - Error converting date and/or time from character string - sql

I have a datetime column which I'm checking for null. All I want to do is have it say "No Next Appointment" if the column is null. However I'm getting an error:
conversion failed when converting date and/or time from character string
I'm not sure why. I tried a couple different ways to write the query but it keeps giving me the same error.
Here is my query-
SELECT
t1.PatientID,
t1.FullName,
t1.CurrentRAF_DW,
t1.NumberOfCompletedClinicVisits,
t1.PreferredServiceLocation,
case when t1.IsVip = 1 then 'Yes' else 'No' end as [IsVip],
case when t1.PatientTier = 'Critical' then 'Every Three Weeks'
when t1.PatientTier = 'Serious' then 'Every 1 Month'
when t1.PatientTier = 'Fair' then 'Every 2 Months'
when t1.PatientTier = 'Good' then 'Every 3 Months'
else ' '
end as [Cadence],
t1.PatientTier,
t2.hcc_18,
t2.hcc_19,
t2.hcc_21,
t2.hcc_22,
t2.hcc_12,
t2.hcc_136,
t2.hcc_137,
t2.hcc_108,
t2.hcc_88,
t2.hcc_111,
t2.hcc_85,
t2.hcc_55,
t1.LastCompletedClinicVisit,
case when t1.NextScheduledClinicVisit is not null then t1.NextScheduledClinicVisit else 'No Next Appointment' end as [NextScheduledVisit]
FROM vw_patient_attributes t1
INNER JOIN STG_OSHODS_DW.osh_rpt.dim_member_care_measures t2
ON t1.PatientID = t2.emr_id
The column in question here is "NextScheduledClinicVisit".

First, you should use coalesce(). Second, the types should match:
coalesce(convert(varchar(255), t1.NextScheduledClinicVisit ),
'No Next Appointment'
) as [NextScheduledVisit]
If NextScheduledClinicVisit is a sting, then you probably want to use an appropriate conversion specification (such as 121) or use format().

The column will sometimes contain a datetime field and sometimes a string.
Try casting the datetime to a varchar.

I'd go about solving your issue using the following method.
Wrap the error generating column in a try_convert and review some sample records
If above successful write your case statement using a "case when [col] is null then 'formatted text 1' ..." type statement and review some sample records
Apparently Gordon's answer is working so use that, but I might look into try_Convert for future reference.

Related

Using BETWEEN function

I have this query, using which I am trying to categorize my data. If the first character is between 0 and 9, I want to categorize it with the first character. If it is anything else including special characters or alphabets, then I want to use 10.
select CUSTOMER_ID, CASE
WHEN LEFT(CUSTOMER_ID, 1) BETWEEN 0 AND 9 THEN LEFT(CUSTOMER_ID, 1)
ELSE '10'
END
AS CUST_DIGIT
from CUSTOMER
I get this error when I run the above query:
Conversion failed when converting the nvarchar value 'A' to data type
int.
This is what my data looks like. Could you please help point what I could change.
Update your between values to string as '0' AND '9' then it will work.
Reason you are getting error is when you perform LEFT it will return string and you are comparing it with int as 0 AND 9 are int, So it will try to convert your result value from LEFT to int.
Your some of the record have digit at beginning of value those will work fine but when record comes like A46564 it won't be able to cast A to int and throw error.
SELECT CUSTOMER_ID, CASE
WHEN LEFT(CUSTOMER_ID, 1) BETWEEN '0' AND '9' THEN LEFT(CUSTOMER_ID, 1)
ELSE '10'
END AS CUST_DIGIT
FROM CUSTOMER
I would initially answer the same as #Karan.
Just for completeness... In your case, a possible alternative would be to use ISNUMERIC:
select
CUSTOMER_ID,
CASE
WHEN ISNUMERIC(LEFT(CUSTOMER_ID, 1)) = 1 THEN LEFT(CUSTOMER_ID, 1)
ELSE '10'
END AS CUST_DIGIT
from
CUSTOMER
And yet another approach would be to use the LIKE operator:
select
CUSTOMER_ID,
CASE
WHEN CUSTOMER_ID LIKE '[0-9]%' THEN LEFT(CUSTOMER_ID, 1)
ELSE '10'
END AS CUST_DIGIT
from
CUSTOMER

Teradata - selecting between two columns based on whether it starts with a number or not

I have the a query which looks similar to:
SELECT
s.cola, s.colb, t.colc, t.cold, u.cole, u.colf, u.colg, u.colh, u.coli, u.colj, u.colk, u.coll
FROM table1 s
INNER JOIN table2 t
ON s.colb = t.colc
INNER JOIN table3 u
ON u.colm = t.cold
WHERE cast(s.cola as date) between date '2017-11-06' and date '2017-11-10'
ORDER BY 3
I need to add a new column, called col_new, which is to be filled by either u.colm or u.coln. This column will have values from u.colm if that column starts with a number. Otherwise it will have values from u.coln. It is known that either u.coln or u.colm starts with a number, for each entry in table u.
I tried the following query to test if entries starting with a number can be identified or not:
SELECT CASE WHEN ISNUMERIC(SUBSTRING(LTRIM(colm), 1, 1)) = 1
THEN 'yes'
ELSE 'no'
END AS col_new
FROM table_u
It returned the error: Syntax error: expected something between '(' and the 'substring' keyword.
Kindly suggest a solution.
Edit:
Exact Error:
[Teradata Database] [3706] Syntax error: expected something between '(' and the 'substring' keyword.
Instead of isnumeric(), just do a comparison:
SELECT (CASE WHEN LEFT(LTRIM(colm), 1) BETWEEN '0' AND '9' THEN 'yes'
ELSE 'no'
END) AS col_new
FROM table_u;
LEFT() is a convenient shorthand for the first "n" characters of a string.

String data right truncation DB2 error

I am receiving the error "String data right truncation" on db2 when I use this query
SELECT BILL_NUMBER, 'PAPERWORK BUT NOT COMPLETE', 'NONE', NULL, '00000',NULL,NULL,TOTAL_CHARGES, NULL FROM TLORDER WHERE
CURRENT_STATUS NOT IN ('COMPLETE','APPRVD','PAPERWISE','BILLD','EDIBILLED','CANCL') AND BILL_TO_CODE NOT LIKE CASE WHEN :INCLUDE_DED = 'No' THEN 'ROCD%' ELSE '1234kkh5656' END
AND EXISTS (SELECT 1 FROM LIST_CHECKIN_AUDIT A WHERE A.BILL_NUMBER = TLORDER.BILL_NUMBER FETCH FIRST 1 ROW ONLY)
AND SITE_ID = :SITE AND DELIVER_BY_END >= CURRENT TIMESTAMP - 3 MONTHS AND COALESCE(PICK_UP_DRIVER,'') = '' AND '00000' =:DRIVER_ID
However when I suppress this line I do not get the error.
AND BILL_TO_CODE NOT LIKE CASE WHEN :INCLUDE_DED = 'No' THEN 'ROCD%' ELSE '1234kkh5656' END
Thanks in advance!
I'd venture to guess that this happens when the value of the :INCLUDE_DED host variable exceeds 2 bytes in length. You do not supply the variable data type, so the query compiler derives it from the right side of the comparison, where the literal 'No' has the length of 2 bytes. If you then assign a value like 'Yes' to the host variable it has to be truncated.
Consider adding an explicit type information to the host variable reference, e.g.:
...WHEN CAST(:INCLUDE_DED AS VARCHAR(10)) = 'No'...
Use the data type appropriate for the range of possible values.
I would first check the datatype of the bill_to_code. You are returning '1234kkh5656' that may exceed the length of the datatype.

sql case statement with date values

I have a date column in my database table.
SELECT sDestructionDate FROM tblDocumentHeader
below is the result of above query
I need to print empty for the date value '1991-01-01'
I expect a result set something like below.
I tried the below query but it still print that '1991-01-01' date.
SELECT CASE CONVERT(date,h.sDestructionDate,103)
WHEN '01/01/1991'
THEN ''
ELSE CONVERT(date,h.sDestructionDate,103) END
AS 'sDestructionDate'
FROM tblDocumentHeader h
I don't want to convert the result into varchar value. below query does gives me the result but i need to return it from date format.
SELECT CASE CONVERT(varchar,h.sDestructionDate,103)
WHEN '01/01/1991'
THEN ''
ELSE convert(varchar,h.sDestructionDate,103) END
AS 'sDestructionDate'
FROM tblDocumentHeader h
I would first convert it to a null:
select
case
when h.sDestructionDate = '01/01/1991' then null
else h.sDestructionDate
end as sDestructionDate
from tblDocumentHeader h
Then look to your reporting tool to present a blank if the value is null
Mixing data with presentation is a mistake. This approach is simple and keeps the two concerns of data and rendering separate.

sql - conversion error when changing 'and' to 'or'

I have a database table in sql server 2008. My query is breaking for a reason that is unknown to me:
select release_id, url_id,tt_projectid, release_title, tech_area, current_state, dateadd(ss,last_built,'12/31/1969 20:00:00') as recent_Date,
autobuild_count, manualbuild_count, bcm_build_count, config_count, force_count, transition_only_count,
auto_integ_count,last_auto_integ,dateadd(ss,integ_complete_date,'12/31/1969 20:00:00') as integ_date
from tablename
where (auto_integ_count > 0
and MONTH(last_auto_integ) = '1'
and YEAR(last_auto_integ) = '2013')
and (release_id > 36000)
order by release_id desc
The above query works fine, but when I change the last line of the where close from 'and' to 'or' I get this conversion error:
Conversion failed when converting date and/or time from character string.
I'm puzzled as to why changing
'and (release_id > 36000)'
to
'or (release_id > 36000)'
would cause such an error
The reason is because last_auto_integ is being stored as a string rather than as a date. These lines in the where clause are not being executed with the and -- by happenstance -- because none occur when release_id > 360000.
From what I can see, there are no other places in the query where you might be converting a string to a date format.
You can identify these values using:
select last_auto_integ
from tablename
where isdate(last_auto_integ) = 0 and last_auto_integ is not null
You can fix the problem in the query by using case:
where month(case when isdate(last_auto_integ) = 1 then last_auto_integ end) = 1 and
year(case when isdate(last_auto_integ) = 1 then last_auto_integ end) = 2013
Or, you can just use substring() to extract the month and year from whatever date format you are using.
Because when you change AND to OR you are getting a lot more rows returned, and one of these other expressions is failing:
dateadd(ss,integ_complete_date,'12/31/1969 20:00:00')
MONTH(last_auto_integ)
YEAR(last_auto_integ)
With only AND, it doesn't need to evaluate the other expressions for rows whose release_id is <= 36000, so it's not encountering the strings that are causing the problem on date conversion.