Searching set of characters in a string - sql

How to query if i want to check if string contains numbers(characters) like 1,2,3,4,5,6,7 in any order. It can be achieved by writing AND statements on LIKE clause for number 1,2..and so on like below,
Where days like '%1%' and days like '%2%' ...... So on
Is there any query which check specific characters present in string. or how above example can achieve with a short hand query. Please help. Thanks.

One way to do this is create a table with all the string you like to search.
e.g.
DECLARE #searchstr TABLE (s VARCHAR(10))
INSERT INTO #searchstr VALUES ('1'),('2'),('3'),('4'),('5'),('6'),('7')
DECLARE #tbl TABLE (days VARCHAR(100))
INSERT INTO #tbl VALUES ('1234567'),('123'),('1122334'),('7654321')
SELECT t.days
FROM #tbl t
LEFT JOIN #searchstr s
ON t.days LIKE '%' + s.s+ '%'
GROUP BY t.days HAVING COUNT(DISTINCT s.s) = 7

Will not CONTAINS() work for you?
Also notice how to split word into char array.

I would suggest looking into [PATINDEX][1]. From MSDN:
Returns the starting position of the first occurrence of a pattern in
a specified expression, or zeros if the pattern is not found, on all
valid text and character data types.
You probably will end up using something like WHERE PATINDEX(%[0-9]%', foo) > 0

You can use CHARINDEX
CHARINDEX(stringthatcontainschars1, '1', numofpositiontostartlookingat)
Output: 24, the position that your searched for char is at. returns zero if not found
if you were looking for the number 1 in a column or a string you would put:
CHARINDEX(columnname, '1', 1)
This would search for '1' beginning at position 1.
You can do an conditional statement based on whether or not it returns 0 to decide if char is in string or not and write whatever code you need after that.

I'd use isnumeric to ensure they're all digits, then test for 0, 8, or 9 instead of 1-7 because it's shorter.

If days are coma separated you can use FIND_IN_SET
SELECT FIND_IN_SET(1, days) AND FIND_IN_SET(2, days);
It is different, not better, but as far as I know there is no other native way.
And LIKEs probably will be much faster then find_in_set

Related

Extract only numeric values from String column

I have a column of values that are as shown below:
ID
x-644478134
x-439220334
x-645948923
x-10686843432
x-4273883234
I would like to return a column like so:
ID
644478134
439220334
645948923
10686843432
4273883234
Can someone advise how to do this cleanly? I believe it is something to do with substring but not sure exactly
SELECT SUBSTRING(d.ID)
FROM data d
You need to use substring, charindex and len functions such as below, assuming the dash (-) is the separator of the text and numeric part:
declare #x varchar(50) = 'a-0123'
select substring(#x,CHARINDEX('-',#x,1)+1,len(#x)-CHARINDEX('-',#x,1))
If you are sure that ID always starts with x-, then:
Select substring(ID,3,LEN(ID)-2)

Sort a VARCHAR column in SQL Server that contains numbers?

I have a column in which data has letters with numbers.
For example:
1 name
2 names ....
100 names
When sorting this data, it is not sorted correctly, how can I fix this? I made a request but it doesn’t sort correctly.
select name_subagent
from Subagent
order by
case IsNumeric(name_subagent)
when 1 then Replicate('0', 100 - Len(name_subagent)) + name_subagent
else name_subagent
end
This should work
select name_subagent
from Subagent
order by CAST(LEFT(name_subagent, PATINDEX('%[^0-9]%', name_subagent + 'a') - 1) as int)
This expression will find the first occurrence of a letter withing a string and assume anything prior to this position is a number.
You will need to adapt this statement to your needs as apparently your data is not in Latin characters.
With a bit of tweaking you should be able to achieve exactly what you're looking for:
select
name_subagent
from
Subagent
order by
CAST(SUBSTRING(name_subagent,0,PATINDEX('%[A-Z]%',name_subagent)) as numeric)
Note, the '%[A-Z]%' expression. This will only look for the first occurrence of a letter within the string.
I'm not considering special characters such as '!', '#' and so on. This is the bit you might want to play around with and adapt to your needs.

Substring of a specific occurence

I have a column as varchar2 datatype, the data in it is in format:
100323.3819823.222
100.323123.443422
1001010100.233888
LOL12333.DDD33.44
I need to remove the whole part after the first occurrence of '.'
In the end it should look like this:
100323
100
1001010100
LOL12333
I cant seem to find the exact substring expression due to the fact that there is not any fix length of the first part.
One way is to use REGEXP_SUBSTR:
SELECT REGEXP_SUBSTR(column_name,'^[^.]*') FROM table
The other way is to combine SUBSTR with INSTR, which is a bit faster, but will result in NULL if the data doesn't contain a dot, so you'll have to add a switch if needed:
SELECT SUBSTR(column_name, 1, INSTR(column_name,'.') - 1) FROM table
For oracle you can try this:
select substr (i,1,Instr(i,'.',i)-1) from Table name.

Get total number of user where username have defferrent case

I have SQL table where username have different cases for example "ACCOUNTS\Ninja.Developer" or "ACCOUNTS\ninja.developer"
I want to find the how many records where username where first in first and last name capitalize ? how can use Regex to find the total ?
x table
User
"ACCOUNTS\James.McAvoy"
"ACCOUNTS\michael.fassbender"
"ACCOUNTS\nicholas.hoult"
"ACCOUNTS\Oscar.Isaac"
Do you want something like this?
select count(*)
from t
where name rlike 'ACCOUNTS\[A-Z][a-z0-9]*[.][A-Z][a-z0-9]*'
Of course, different databases implement regular expressions differently, so the actual comparator may not be rlike.
In SQL Server, you can do:
select count(*)
from t
where name like 'ACCOUNTS\[A-Z][^.][.][A-Z]%';
You might need to be sure that you have a case-sensitive collation.
In most cases in MS SQL string collation is case insensitive so we need some trick. Here is an example:
declare #accts table(acct varchar(100))
--sample data
insert #accts values
('ACCOUNTS\James.McAvoy'),
('ACCOUNTS\michael.fassbender'),
('ACCOUNTS\nicholas.hoult'),
('ACCOUNTS\Oscar.Isaac')
;with accts as (
select
--cleanup and split values
left(replace(acct,'ACCOUNTS\',''),charindex('.',replace(acct,'ACCOUNTS\',''),0)-1) frst,
right(replace(acct,'ACCOUNTS\',''),charindex('.',replace(acct,'ACCOUNTS\',''),0)) last
from #accts
)
,groups as (--add comparison columns
select frst, last,
case when CAST(frst as varbinary(max)) = CAST(lower(frst) as varbinary(max)) then 'lower' else 'Upper' end frstCase, --circumvert case insensitive
case when CAST(last as varbinary(max)) = CAST(lower(last) as varbinary(max)) then 'lower' else 'Upper' end lastCase
from accts
)
--and gather fruit
select frstCase, lastCase, count(frst) cnt
from groups
group by frstCase,lastCase
Your question is a little vague but;
You might be looking for the DISTINCT command.
REF
I don't think you need regex.
Maybe do something like:
Get distinct names from Table X as Table A
Use inputs table A as where clause on Table X
count
union
I hope this helps,
Rhys
Given your example set you can use a combination of techniques. First if the user name always begins with "ACCOUNTS\" then you can use substr to select the characters that start after the "\" character.
For the first name:
Then you can use a regex function to see if it matches against [A-Z] or [a-z] assuming your username must start with an alpha character.
For the last name:
Use the instr function on the substr and search for the character '.' and again apply the regex function to match against [A-Z] or [a-z] to see if the last name starts with an upper or a lower character.
To total:
Select all matches where both first and last match against upper and do a count. Repeat for the lower matches and you'll have both totals.

patindex parterns

I'm trying to trim a column (ActionOutput) to only show two substrings in that column.
I need to only show the 8 characters entries that starts with either WRD or CAS.
The column can have any types/numbers of characters and they won't always contains entries with the specified patterns.
My query looks like this:
SELECT
TSRPT_C009 = ExecutionTime,
LastStatusMessageID,
LastStatusMessageIDName,
TSRPT_C007 = ExitCode,
TSRPT_C008 = ActionOutput,
(PATINDEX('%[cas][wrd]%',ActionOutput)) AS CASID
FROM v_TaskExecutionStatus tse
I also tried this:
substring(
(substring(ActionOutput,(CHARINDEX('WRD0',ActionOutput)),8)),(CHARINDEX('CAS0',ActionOutput)),8
) AS CASID
But it also didn't work for the second pattern.
Is there a way to search for multiples patterns in a string (returned from a select) and return it/them.
Thks in advance and don't heistate if you have any questions.
Steph
PATINDEX() returns an integer, not a string. You might try this:
(case when ActionOutput like '%cas%'
then substring(ActionOutput, charindex('cas', ActionOutput), 8)
when ActionOutput like '%wrd%'
then substring(ActionOutput, charindex('wrd', ActionOutput), 8)
end) as caswrd_8