Try this: SQL Fiddle
select Id
, ErrorType
, (len(ErrorDescr) - len(replace(ErrorDescr, ErrorType, '')))/nullif(len(ErrorType),0) Count
from
(
select Id
, ErrorDescr
, case
when ErrorDescr like 'Error:%- E__ -%' then
substring(ErrorDescr, charindex('-',ErrorDescr)+2, 3)
else
ErrorDescr
end ErrorType
from Error
) subQuery
What's going on?
The case
statement allows us to choose the appropriate logic for handling those lines beginning Error:
vs those which don't. I've used the expression ErrorDescr like 'Error:%- E__ -%'
to ensure that as well as beginning Error:
, the string should also contain a hyphen followed by a space then a 3 char code starting E before another space and hyphen, then whatever.
To get the substring we just use the substring
function: substring(ErrorDescr, charindex('-',ErrorDescr)+2, 3)
. We find the position of the first hyphen, then move forwards two places to find the space, then the E (the first char of our 3 char code). Starting at this character (E) we take 3 characters, getting our full code.
We put this in a subquery so that our code is available to us in the outer query, rather than us having to recalculate this value in order to calculate the count. The code to count the occurrences of the code in the description is: (len(ErrorDescr) - len(replace(ErrorDescr, ErrorType, '')))/nullif(len(ErrorType),0)
. Here we take the difference between the full description's length and the length of the description with all instances of the code removed to get a value representing the number of characters removed. We then divide this by the number of characters in the code to get the number of codes removed. e.g. if we have a string of 12 characters containing 2 instances of a 3 char code we'd have (12 - 6) / 3
, giving us 2
. The nullif
is included so that if the code were somehow 0 (possible if ErrorDescr is blank, or if the code to capture the error code were amended), we'd avoid a divide 0 error, instead saying the count is null when there are no codes to count.
Update
Regarding taking 10 chars when the code doesn't start with an E, you can amend your case statement like this: SQL Fiddle
, case
when ErrorDescr like 'Error:%- E__ -%' then
substring(ErrorDescr, charindex('-',ErrorDescr)+2, 3)
when ErrorDescr like 'Error:%- %' then
substring(ErrorDescr, charindex('-',ErrorDescr)+2, 10)
else
ErrorDescr
end ErrorType
i.e. The scenario where the code starts with E is handled by the first when
statement; so for those values the second when
(which would also match those values) isn't hit; but those values beginning Error:
which don't have an E code fall through to this second one and get handled here, taking the 10 characters. Any which match neither fall through to the else
statement and the full string is returned.