Separate One Column Into Two Columns - sql-server-2008

I'm trying to separate one column that contains a blood type into two columns.
For example, if my value is ABNG in the existing blood type column, I want to separate this into two new columns and insert the values: AB and Neg.
Not sure if a case statement will handle this, but I tried different variations and could not find a solution.
Here is what the existing data looks like, there are 9 blood types (including the Unknown which is fine) with some bad data mixed in (' ', 0, and B).
Without having the best grasp on how to handle this I am thinking a view could be created that would split the information into new columns.
And this is what I'm hoping the end result to be:
Is this possible?

You can use CASE statement for checking conditions and wildcard characters for string filtration for the source column.
SELECT PBTYPE [Existing Blood Type],
CASE
WHEN PBTYPE LIKE 'O%' THEN 'O'
WHEN LEFT(PBTYPE,1)='A' AND SUBSTRING(PBTYPE,2,1)<>'B' THEN 'A'
WHEN LEFT(PBTYPE,2)='AB' AND SUBSTRING(PBTYPE,2,1)='B' THEN 'AB'
WHEN PBTYPE LIKE 'B%' THEN 'B'
WHEN PBTYPE = 'UNK' THEN 'UNK'
END [Blood Type],
CASE
WHEN PBTYPE LIKE '%POS' OR PBTYPE LIKE '%PS' THEN 'POS'
WHEN PBTYPE LIKE '%NEG' OR PBTYPE LIKE '%NG' THEN 'NEG'
WHEN PBTYPE LIKE '%B' THEN 'B'
WHEN PBTYPE LIKE '%UNK' THEN 'UNK'
END [Rho]
FROM YOURTABLE
WHERE PBTYPE <> '' AND PBTYPE <> '0'
Click here to view result

Given that there's a limited number of blood types (and hoping that your data is formatted well), you could do something like:
SELECT Type = CASE WHEN col LIKE 'AB%' THEN 'AB' /*gets AB*/
ELSE LEFT(col, 1) /*gets o,a,or b*/ END,
Valence = RIGHT(col, 3) /*gets pos or neg*/

Related

mySQL: How to display a string upon encountering a specific string in a column using CASE?

What I want to accomplish is that, when I encounter the string Rotterdam, I want to replace it with N/A
I was able to do it using IF command, can someone tell me why my CASE command is giving error?
Code:
If
SELECT id,if(name like 'rotterdam','N/A',name)
,
COUNTRYCODE,
DISTRICT,
POPULATION
FROM city
LIMIT 10;
Case (incorrect)
SELECT id,/* if(name like 'rotterdam','N/A',name) */
CASE
WHEN name LIKE 'ROTTERDAM' THEN 'N/A'
ELSE SELECT name
END,
COUNTRYCODE,
DISTRICT,
POPULATION
FROM city
LIMIT 10;
The table:
[Table image]
My approach: [using case command] (you can see the error here)
[using if command (works)]
Desired Output: [you can see N/A in the second column]
Don't use a second select:
(CASE WHEN name LIKE 'ROTTERDAM' THEN 'N/A'
ELSE name
END)
You could use SELECT, but it would be silly and require a subquery:
(CASE WHEN name LIKE 'ROTTERDAM' THEN 'N/A'
ELSE (SELECT name)
END)
Note that the SELECT (without parentheses) would not work with IF() either.

SQL select value and then use in sub query to replace string

In my sql table I have a number of values as follows;
<![CDATA[9435547092]]>
<![CDATA[Company Name]]>
Most of the rows have a CDATA wrap, I wanted to remove this from all the files so I was thinking a subquery would be good something like;
SELECT value FROM attributes WHERE value LIKE "%<![CDATA[%";
Would give me each value and then I was thinking to do
SELECT REPLACE(SELECT value FROM attributes WHERE value LIKE "%<![CDATA[%";, "<![CDATA[", '') FROM attributes
But this isn’t valid, anyone know how this is possible?
just use replace in select for obatin the right string
SELECT replace(value , "<![CDATA[", '')
FROM attributes
WHERE value LIKE "%<![CDATA[%";
if you need store in databae then you need updated
UPDATE attributes
set value = replace(value , "<![CDATA[", '')
WHERE value LIKE "%<![CDATA[%";
but seems you are looking for the left string after LIKE "%
select right(value, length(value) - locate(value,']]')+2)
from attributes
WHERE value LIKE "%<![CDATA[%";
UPDATE attributes
set value = right(value, length(value) - locate(value,']]')+2)
WHERE value LIKE "%<![CDATA[%";
Does this do what you want?
select replace(replace(value, '<![CDATA[', ''), ']]>', '')
Note that if your actual value has "wraps", then this might affect the value. I think a more generic method would be:
select (case when value like '<![CDATA[%]]>'
then substr(value, 9, length(value) - 3)
else value
end)
Please try this,
SELECT select SUBSTRING(value,10,LEN(value)-12)
FROM attributes
WHERE value like '<![CDATA[%'
If needed where clause could be removed and as suggested above could be used with CASE statement.

Why is CASE WHEN acting backwards in this query?

I'm trying to use CASE WHEN to group multiple possible values in a SQL view. It works, but backwards and I'd like to understand why.
SELECT DISTINCT
name,
CASE
WHEN name NOT LIKE '%Value1%' THEN 'Group1'
WHEN name NOT LIKE '%Value2%' THEN 'Group2'
WHEN name NOT LIKE '%Value3%' THEN 'Group3'
ELSE name
END AS 'filtered name'
FROM sometable;
This actually gives me the output that I need:
Anything that contains Value1 is put in Group1
Anything that contains Value2 is put in Group2
Anything that contains Value3 is put in Group3
Anything else keeps it's current name
Now, I expected the query for this result to be the one I currently have without any 'NOT' before the 'LIKE' operators, and I am quite confused that this works, I am trying to understand what's happening.

Using Between Command in SQL

I have the following table
drink_name........cost........calories
Black.............1...........30
Clue..............2...........40
Elephant----------3...........50
When I use the between command for characters (it excludes ending positions)
select drink_name from drink_info where drink_name between 'B' and 'C';
output:
Black
Note that Clue is omitted.
Now when using between for number comparison (it includes the ending position)
select drink_name from drink_info where cost between 1 and 3
Output:
1
2
3
Note that 3 is included.
Why is there a behaviour difference of the between keyword between integer and characters, because it includes the last number (3) whereas last character (Clue) is excluded
Between works in exactly the same way in both cases. It include both end points.
The difference is in how integers differ from strings (and floats and datetimes).
For this reason, it is often better to use < for the second comparison:
select drink_name
from drink_info
where drink_name >= 'b' and drink_name < 'c';
This will not include 'c'. If the second comparison were <= then 'c' would be included, but nothing else that begins with 'c'.
If you want to choose drink names with a beginning character between B and C inclusive:
select drink_name from drink_info where left(drink_name, 1) between 'B' and 'C';
The difference is because of the characters following 'C'. To test it out create a drink name in your table called 'C' and execute your query and the output will have C in it.
When you used Between against integer field, you specify the whole integer (and not part of it) and hence you got the result including it.
Just another variant to achieve your goal:
SELECT drink_name
FROM drink_info
WHERE LEFT(drink_name,1) BETWEEN 'B' and 'C';

SQL Server 2008: Case Matrix? Selective Case? Case Association?

In SQL Server 2008 is there an abbreviated way to match CASE boolean expressions, with the values you'd like to select when the expression is true?
Instead of
CASE
when item='a' then 'Apple'
when item='b' then 'Ball'
when item IN ('c','d') then 'Pet'
when item !='zz' then 'object'
else 'Bad_Item'
I would like something resembling one of the following. These are of course pseudo code, but the idea is to bring the association closer and not to keep writing more when/then pairs
Does something like this exist?
CASE
when item ;(=,'a','Apple')
;(=,'b','Ball') ;(=,'c' or 'd','Pet')
;(!='zz','object') ;'Bad item'
END
Does something like this exist?
CASE
when item ;= ('a','b','c' or 'd' : 'Apple','Ball','Pet','Object')
;!= ('zz' : 'Object')
;'Bad item'
END
Again those were pseudo code, but just wanted to know if there is something faster or simpler or with a listing of all the things to check followed by all the values to select.
There is no shorthand like you describe. You can shorten the code a little bit by using the alternate CASE syntax that #sarwar026 mentioned, but the <> line he posted doesn't work. You can't use that form with anything but equality - no inequality, no ranges using between or >=/<=, no IN(), no null checks even.
An example of combining the simple and searched CASE expressions is:
declare #item as VarChar(10) = 'c'
select case #item
when 'a' then 'Apple'
when 'b' then 'Ball'
else case
when #item in ( 'c', 'd' ) then 'Pet'
when #item != 'zz' then 'object'
else 'Bad_Item' end
end
The following works as far I know
CASE item
when 'a' then 'Apple'
when 'b' then 'Ball'
when 'c' then 'Pet'
when 'd' then 'Pet'
// the next line is not possible, so please discard the next line
*when <>'zz' then 'object' // not sure about this syntax*
else 'Bad_Item'
END