Error in SQL case statement when trying to create binary flag? - sql

Here's my query where I'm testing my case structure:
SELECT TOP 1 CASE 130
WHEN '000000000000000' THEN '0'
WHEN '' THEN '0'
WHEN 'XXX' THEN '0'
WHEN 'RETIRED' THEN '0'
WHEN 'STUDENT' THEN '0'
ELSE '1'
END AS employed_flag
INTO #employedbeta
FROM CreditBureau.Experian
I'm just trying to make a new temporary table, but I'd like my case to work first. I keep getting the error:
Conversion failed when converting the varchar value 'XXX' to data type int.
In the database, the column 130 is a char, and I don't know why it thinks I want to make it a number. SQL server management studio, if it matters.
The column name is 130, I left the '1' off because I rewrote it here but I get the error regardless in my actual query.

130 is an integer literal. If that's really the column name, you'll have to escape it using double quotes. As a side note, you should probably return the same type (char) in the else branch too:
CASE "130"
WHEN '000000000000000' THEN '0'
WHEN '' THEN '0'
WHEN 'XXX' THEN '0'
WHEN 'RETIRED' THEN '0'
WHEN 'STUDENT' THEN '0'
ELSE '1'
END AS employed_flag

130 is a really bad column name. But, I would simplify the logic to:
SELECT TOP 1 (CASE WHEN [130] IN ('000000000000000', '', 'XXX', 'RETIRED', 'STUDENT')
THEN 0 ELSE 1
END) AS employed_flag
INTO #employedbeta
FROM CreditBureau.Experian;
Note that I also changed the employed_flag to a numeric value rather than a string. That makes more sense to me.

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

Invalid argument for function integer IBM DB2

I need to filter out rows in table where numer_lini column has number in it and it is between 100 and 999, below code works just fine when i comment out line where i cast marsnr to integer. However when i try to use it i get error: Invalid character found in a character string argument of the function "INTEGER". when looking at the list seems like replace and translate filters only numbers just fine and select only contains legit numbers (list of unique values is not long so its easy to scan by eye). So why does it fail to cast something? I also tried using integer(marsnr), but it produces the same error. I need casting because i need numeric range, otherwise i get results like 7,80 and so on. As I mentioned Im using IBM DB2 database.
select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where numer_lini in (
select marsnr
from (
select
distinct numer_lini marsnr
from alaska.trasa
where case
when replace(translate(numer_lini, '0','123456789','0'),'0','') = ''
then numer_lini
else 'no'
end <> 'no'
)
where cast(marsnr as integer) between 100 and 999
)
fetch first 300 rows only
If you look at the optimized SQL from the Db2 explain, you will see that Db2 has collapsed your code into a single select.
SELECT DISTINCT Q2.NUMER_LINI AS "NUMER_LINI",
Q2.WAR_TRASY AS "WAR_TRASY",
Q2.ID_PRZ1 AS "ID_PRZ1",
Q2.ID_PRZ2 AS "ID_PRZ2",
Q1.NUMER_LINI
FROM ALASKA.TRASA AS Q1,
ALASKA.TRASA AS Q2
WHERE (Q2.NUMER_LINI = Q1.NUMER_LINI)
AND (100 <= INTEGER(Q1.NUMER_LINI))
AND (INTEGER(Q1.NUMER_LINI) <= 999)
AND (CASE WHEN (REPLACE(TRANSLATE(Q1.NUMER_LINI,
'0',
'123456789',
'0'),
'0',
'') = '') THEN Q1.NUMER_LINI
ELSE 'no' END <> 'no')
Use a CASE to force Db2 to do the "is integer" check first. Also, you don't check for the empty string.
E.g. with this table and data
‪create‬‎ ‪TABLE‬‎ ‪alaska‬‎.‪trasa‬‎ ‪‬‎(‪numer_lini‬‎ ‪VARCHAR‬‎(‪10‬‎)‪‬‎,‪‬‎ ‪war_trasy‬‎ ‪INT‬‎ ‪‬‎,‪‬‎ ‪id_prz1‬‎ ‪INT‬‎,‪‬‎ ‪id_prz2‬‎ ‪INT‬‎)‪;
insert into alaska.trasa values ('',1,1,1),('99',1,1,1),('500',1,1,1),('3000',1,1,1),('00300',1,1,1),('AXS',1,1,1);
This SQL works
select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where case when translate(numer_lini, '','0123456789') = ''
and numer_lini <> ''
then integer(numer_lini) else 0 end
between 100 and 999
Although that does fail if there is an embedded space in the input. E.g. '30 0'. To cater for that, a regular expressing is probably preferred. E.g.
select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where case when regexp_like(numer_lini, '^\s*[+-]?\s*((\d+\.?\d*)|(\d*\.?\d+))\s*$'))
then integer(numer_lini) else 0 end
between 100 and 999

PSQL - invalid input syntax for type double precision: "null";

I'm writing a query to pull some data and running into this invalid input syntax for type double precision: "null" error and am not entirely sure the meaning behind it and/or haven't figured out a solution. The column I'm running the case statment on does have null values in it or it has the appropriate value that i need.
account id col could have strings or it has null values
I've tried:
case
when length(account_id) > 1
then account_id
else
'null'
end as account_id,
and
case
when account_id is not null
then account_id
else
'null'
end as account_id,
both resulting in Invalid operation: invalid input syntax for type double precision: "null";
When i just put this in a column and use the length(account_id) it will show the length or just display null - why wouldn't this work in a case statement?
Thanks!
'null' is a string. null is . . . well null. Your account_id appears to be of type double precision. That is a strange choice for an account_id, but inappropriate data types are not relevant. What is relevant is that the case expression wants everything to be of the same type, with numbers getting precedence.
You may want one of these two things:
(case when length(account_id) > 1 then account_id end) as account_id,
The default is null when there is no else. You could add else null, but that is redundant.
Or:
(case when length(account_id) > 1 then account_id::varchar(255) else 'null' end) as account_id,

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.

Replacing a word with a number in SQL Server

I have a table which has 12 columns containing a word, I want to change this to a number. For instance: each of these 12 columns can have one of 5 pre-specified possible values of:
highly agree
agree
no opinion
disagree
highly disagree
I want to change these words with a number, the problem is the data type, it does not allow me to change a nvarchar data type to number, I even tried text data type to contain { highly agree, agree , no opinion , disagree, highly disagree } and then changed them to numbers but this error appeared:
Msg 402, Level 16, State 1, Line 1
The data types text and varchar are incompatible in the equal to operator.
The query I used was this:
[A1]= (case when [A1]='highly agree' then 1
when [A1]='agree' then 4
when [a1]='نظری ندارم' then 9
when [a1]='موافقم' then 16
when [a1]='کاملا موافقم' then 25
else [A1] end )
You dont need to convert your column to text data type, but you have to use your numbers as varchar in your case statement. You cannot mix up data types in the case statement
[A1]= (case when [A1]='highly agree' then '1' when [A1]='agree' then '4' when [a1]='نظری ندارم' then '9' when [a1]='موافقم' then '16' when [a1]='کاملا موافقم' then '25' else [A1] end )
Further to your question, if you want to keep the calculation on this field then you have to cast the whole column to Number. As an example you can use this query
[CalculatedColumn]= CAST(case when [A1]='highly agree' then '1'
when [A1]='agree' then '4'
when [a1]='نظری ندارم' then '9'
when [a1]='موافقم' then '16'
when [a1]='کاملا موافقم' then '25'
else '999' end ) AS INT) -- Any other number which can cast to integer
Try this:
SELECT (CASE A1 WHEN 'highly agree' THEN '1'
WHEN 'agree' THEN '4'
WHEN 'نظری ندارم' THEN '9'
WHEN 'موافقم' THEN '16'
WHEN 'کاملا موافقم' THEN '25'
ELSE A1
END) AS A1