SQL detect sequences of the same character? - sql

I have a table filled with items which have IDs of characters.
Example:
"TGHZN"
"FVGHR"
"OLTVD"
"EERFV" -- invalid because of EE (sequence of the same character)
"EFEDC"
"DFFFB" -- invalid because of FFF
How can I select all rows with invalid IDs?
A invalid ID is defined by a sequence of the equal characters (e.g. AA) within the ID.
I've tried it with RegEx without success: SELECT * FROM Items WHERE ID LIKE '%(.)\1+%'

Another option (no limit on the length of ID)
Select Distinct A.ID
From YourTable A
Join (Select Top 26 Patt=Replicate(Char(64+Row_Number() Over (Order By Number)),2) From master..spt_values ) B
on CharIndex(B.Patt,A.ID)>0

This is not easy to do with SQL Server because SQL Server does not support regular expressions (calling the mild enhancements to 'LIKE' "regular expressions" is serious marketing-overspeak).
Assuming your ids have a length of 5, you can try something like this:
where (id like '%' + substring(id, 1, 1) + substring(id, 1, 1) + '%') or
(id like '%' + substring(id, 2, 1) + substring(id, 2, 1) + '%') or
(id like '%' + substring(id, 3, 1) + substring(id, 3, 1) + '%') or
(id like '%' + substring(id, 4, 1) + substring(id, 4, 1) + '%')
SQL Server does not (out-of-the-box) support regular expressions.
Actually, the replicate() function would make the logic a tad clearer:
where (id like '%' + replicate(substring(id, 1, 1), 2) + '%') or
(id like '%' + replicate(substring(id, 2, 1), 2) + '%') or
(id like '%' + replicate(substring(id, 3, 1), 2) + '%') or
(id like '%' + replicate(substring(id, 4, 1), 2) + '%')

Remove the '+' from the expression you have written. following should work:
SELECT * FROM Items WHERE ID LIKE '%(.)\1%'

Related

Concatenating various characters

I have a series of ID numbers like this
ABC/12345/2012
DEF/67891/2013
GHI/23456/2014
KLM/78911/2014
I need to change them so they look like this
12-12345
13-67891
14-23456
14-78911
14-6634
The below works to a degree but I have a few that only have 4 numbers in, they should be proceeded by a zero.
SELECT RIGHT(ID, 2)+'-'+RIGHT(SUBSTRING(ID, CHARINDEX('/', ID, 1)-1, LEN(ID)-7), 5)
12-12345
13-67891
14-23456
14-78911
14-/6634
So I need 14-/6634 to look like 14-06634
Assuming your column name is ID, and length of each substrings between the '/' characters is not variable (ABC = 3, 12345 = 5, 2012 = 4):
SELECT RIGHT(ID, 2)+'-'+RIGHT(SUBSTRING(ID, CHARINDEX('/', ID, 1)-1, LEN(ID)-7), 5)
Based on your main post edit:
SELECT RIGHT(ID, 2)+'-'+REPLACE(RIGHT(SUBSTRING(ID, CHARINDEX('/', ID, 1)-1, LEN(ID)-7), 5), '/', '0')
Try this
declare #tmp varchar(50) = 'ABC/12345/2012'
select SUBSTRING(#tmp, len(#tmp) - 1, 2) + '-' + SUBSTRING(#tmp,CHARINDEX('/',#tmp)+1,LEN(#tmp))
it gives you
12-12345/2012
and now you have to remove /2012
If your data is fixed format, then you can use PARSENAME
Sample execution with sample data:
DECLARE #TestTable TABLE (TestData VARCHAR (50));
INSERT INTO #TestTable (TestData)
SELECT 'ABC/12345/2012' UNION
SELECT 'DEF/67891/2013' UNION
SELECT 'GHI/23456/2014' UNION
SELECT 'KLM/78911/2014'
SELECT RIGHT(PARSENAME(REPLACE(TestData, '/', '.'), 1), 2) + '-' +
PARSENAME(REPLACE(TestData, '/', '.'), 2) AS TestData
FROM #TestTable
Result:
TestData
--------
12-12345
13-67891
14-23456
14-78911

Replace first or last character is * with % SQL server

I have string:
*rg*niza*io*
I want to replace % in the first and last character of the string. Desired out put is:
%rg*niza*io%
I'm just answering because the obvious to me is:
select '%' + substring(str, 2, len(str) - 2) + '%'
Of course, this would be a bit more complicated if you want to conditionally replace the characters when they are '*'.
If you want to replace only * with % from first and last positions. Then,
Query
SELECT CASE
WHEN LEFT([string_column], 1) = '*' AND RIGHT([string_column], 1) = '*'
THEN '%' + SUBSTRING([string_column], 2, LEN([string_column]) - 2) + '%'
WHEN LEFT([string_column], 1) = '*' AND RIGHT([string_column], 1) <> '*'
THEN '%' + RIGHT([string_column], LEN([string_column]) - 1)
WHEN LEFT([string_column], 1) <> '*' AND RIGHT([string_column], 1) = '*'
THEN LEFT([string_column], LEN([string_column]) - 1) + '%'
ELSE [string_column] END AS [updated_string_column]
FROM [your_table_name];
Demo
Use STUFF,LEFT and LEN string functions
Declare #string varchar(50) = '*rg*niza*io*'
select stuff(left(#string,len(#string)-1),1,1,'%')+'%'
Result : %rg*niza*io%
Use a combination of the CONCAT, LEFT, SUBSTRING & LEFT functions.
SELECT CONCAT('%',LEFT(SUBSTRING(yourfield,2,LEN(yourfield)),LEN(yourfield)-2),'%')
FROM yourtable
Output: %rg*niza*io%

Extract last number out of existing one

I have to extract the next number out of given numbers. My table contains numbers like below. The main product is always with .1 at the end and could or not contains his subproducts e.g:
07.0001.1 (main product)
07.0001.2 (his sub)
07.0001.3 (his sub)
etc..
01.1453.1
01.1453.2
03.3456.1
03.3456.2
03.3456.3
03.5436.1
03.5436.2
03.5436.3
03.5436.4
12.7839.1
12.7839.2
12.3232.1
12.4444.1
12.4444.2
13.7676.1
i want to pass first to digits of a number to the query and based on that get all which starts with that and then get the highest number out of next four and return this number + 1.
So if we would take above example inputs if i say 12 then it should find this product: 12.7839.x and return 12.7839 + 1 so 12.7840
Another example if i say 03 then should find 03.5436 so 03.5436 + 1 so should return 03.5437
Hope you know what i mean.
I am not so familiar with SQL but this is how far i am:
select * from tbArtikel where Nummer LIKE '12.%'
This is another alternate for achieving the desired results. Providing the option to pass number to be queried. Consider following SQL statements
CREATE TABLE tblDummyExample
(
Number VARCHAR(64)
)
INSERT INTO tblDummyExample
VALUES ('07.0001.1')
, ('07.0001.2')
, ('07.0001.3')
, ('01.1453.1')
, ('01.1453.2')
, ('03.3456.1')
, ('03.3456.2')
, ('03.3456.3')
, ('03.5436.1')
, ('03.5436.2')
, ('03.5436.3')
, ('03.5436.4')
, ('12.7839.1')
, ('12.7839.2')
, ('12.3232.1')
, ('12.4444.1')
, ('12.4444.2')
, ('13.7676.1')
DECLARE #startWith VARCHAR(2) = '12' -- provide any number as input
SELECT #startWith + '.'+ CAST((MAX(CAST(SUBSTRING(ex.Number, (CHARINDEX('.', ex.Number, 1) + 1), (CHARINDEX('.', ex.Number, (CHARINDEX('.', ex.Number, 1) + 1)) - (CHARINDEX('.', ex.Number, 1) + 1))) AS INT)) + 1) AS VARCHAR(16))
FROM tblDummyExample ex
WHERE ex.Number LIKE #startWith+'%'
I'm sure, this solution is not restricted to any specific SQL Server version.
Try this, extract the first two parts, convert the 2nd to a numeric value, add one and convert back to a string again:
select
parsename(max(nummer), 3) + '.' -- 03
+ ltrim(max(cast(parsename(nummer, 2) as int) +1)) -- 5436 -> 5437
+ '.1'
from tbArtikel
where Nummer LIKE '03.%'
Try like this,
DECLARE #table TABLE (col VARCHAR(10))
INSERT INTO #table
VALUES ('01.1453.1')
,('01.1453.2')
,('03.3456.1')
,('03.3456.2')
,('03.3456.3')
,('03.5436.1')
,('03.5436.2')
,('03.5436.3')
,('03.5436.4')
,('12.7839.1')
,('12.7839.2')
,('12.3232.1')
,('12.4444.1')
,('12.4444.2')
,('13.7676.1')
SELECT TOP 1 left(col, charindex('.', col, 1) - 1) + '.' + convert(VARCHAR(10), convert(INT, substring(col, charindex('.', col, 1) + 1, charindex('.', col, charindex('.', col, 1) + 1) - (charindex('.', col, 1) + 1))) + 1)
FROM #table
WHERE col LIKE '03.%'
ORDER BY 1 DESC

WHERE clause based on part of a VARCHAR column

I have a query where I need to search the numerical part of a string in SQL Server.
In the number column above needs to be searchable as a variable in the query.
Wildcards does not work:
SELECT PK_Story
FROM Story
WHERE ProductId = #productParam
AND Number LIKE '%' + #numberParam + '%';
because this would also return 132 and 232 for example.
So how can I search for a specific number after the '-'. As you can see I can't do charindex because of the variable prefix length.
What about LIKE '%-' + #numberParam?
You can use substring and charindex combination to get the result.
SELECT PK_Story
FROM Story
WHERE ProductId = #productParam
AND #numberParam like
'%' + case when charindex('-', Number) > 0
then substring(Number, charindex('-', Number) +1, len(Number)) + '%'
else Number
end + '%'
what about this
declare #My_Number as varchar(50)='8'
SELECT PK_Story
FROM Story
WHERE ProductId = #productParam
AND substring(Number, charindex('-', Number) +1, len(Number)) like
#My_Number +'%'
Or, if want equal
SELECT PK_Story
FROM Story
WHERE ProductId = #productParam
AND substring(Number, charindex('-', Number) +1, len(Number)) =
#My_Numbe

SQL Query to parse numbers from name

The DBMS in this case is SQL Server 2012.
I need a SQL query that will grab just the numbers from a device name. I've got devices that follow a naming scheme that SHOULD look like this:
XXXnnnnn
or
XXXnnnnn-XX
Where X is a letter and n is a number which should be left padded with 0's where appropriate. However, not all of the names are properly padded in this way.
So, imagine you have a column that looks something like this:
Name
----
XXX01234
XXX222
XXX0390-A2
XXX00965-A1
I need an SQL query that will return results from this example column as follows.
Number
------
01234
00222
00390
00965
Anyone have any thoughts? I've tried things like casting the name first as a float and then as an int, but to be honest, I'm just not skilled enough with SQL yet to find the solution.
Any help is greatly appreciated!
SQL Server does not have great string parsing functions. For your particular example, I think a case statement might be the simplest approach:
select (case when number like '___[0-9][0-9][0-9][0-9][0-9]%'
then substring(number, 4, 5)
when number like '___[0-9][0-9][0-9][0-9]%'
then '0' + substring(number, 4, 4)
when number like '___[0-9][0-9][0-9]%'
then '00' + substring(number, 4)
when number like '___[0-9][0-9]%'
then '000' + substring(number, 4, 2)
when number like '___[0-9][0-9]%'
then '0000' + substring(number, 4, 1)
else '00000'
end) as EmbeddedNumber
This might work :
SELECT RIGHT('00000'
+ SUBSTRING(Col, 1, ISNULL(NULLIF((PATINDEX('%-%', Col)), 0) - 1, LEN(Col))), 5)
FROM (SELECT REPLACE(YourColumn, 'XXX', '') Col
FROM YourTable)t
SQLFIDDLE
This will work even when XXX can be of different len:
DECLARE #t TABLE ( n NVARCHAR(50) )
INSERT INTO #t
VALUES ( 'XXXXXXX01234' ),
( 'XX222' ),
( 'X0390-A2' ),
( 'XXXXXXX00965-A1' )
SELECT REPLICATE('0', 5 - LEN(n)) + n AS n
FROM ( SELECT SUBSTRING(n, PATINDEX('%[0-9]%', n),
CHARINDEX('-', n + '-') - PATINDEX('%[0-9]%', n)) AS n
FROM #t
) t
Output:
n
01234
00222
00390
00965
If the first 3 chars are always needed to be removed, then you can do something like that (will work if the characters will start only after '-' sign):
DECLARE #a AS TABLE ( a VARCHAR(100) );
INSERT INTO #a
VALUES
( 'XXX01234' ),
( 'XXX222' ),
( 'XXX0390-A2' ),
( 'XXX00965-A1' );
SELECT RIGHT('00000' + SUBSTRING(a, 4, CHARINDEX('-',a+'-')-4),5)
FROM #a
-- OUTPUT
01234
00222
00390
00965
Another option (will extract numbers after first 3 characters):
SELECT
RIGHT('00000' + LEFT(REPLACE(a, LEFT(a, 3), ''),
COALESCE(NULLIF(PATINDEX('%[^0-9]%',
REPLACE(a, LEFT(a, 3), '')),
0) - 1,
LEN(REPLACE(a, LEFT(a, 3), '')))), 5)
FROM
#a;
-- OUTPUT
01234
00222
00390
00965