Search by numeric Value - sql

Using Sql Server 2005
Table1
ID Value
ABC001
BCE002
...
I have search column, when i search the id like this "001" it is showing empty, when I search "ABC001" then it is showing the values.
Query
Select * from table where id = '" & txtid & "'
txtid = textbox
I want to search only the numeric value in the ID.
How to write a query for the numeric search.
Need Query Help

select * from MyTable
where Value LIKE '[A-Z][A-Z][A-Z]001'
OR
select * from MyTable
where Value LIKE '[A-Z][A-Z][A-Z]' + RIGHT('000' + CONVERT(VARCHAR, #id), 3)

SELECT * FROM Table1 WHERE id LIKE '%001'

The answer given by Mitch Wheat will work if every ID you give is 3 letters in caps followed by a numberical value which has 3 digits.
The answer given by rayman86 essentially disregards anything in the front. It merely looks for anything that ends with 001.
If the length of the ID varies and/or the first few characters are not even letters, it's better to use the code that rayman86 has provided. So just use the SELECT * FROM Table WHERE ID LIKE '%Numbers' where Numbers is your numerical value.

A literal interpretation of the question without making any assumptions:
Create this function
create function dbo.numericonly(#s varchar(max))
returns float as
begin
declare #i int set #i = 1
while #i <= len(#s)
if ascii(substring(#s,#i,1)) between 48 and 57
set #i = #i + 1
else
set #s = stuff(#s,#i,1,'')
return #s
end
GO
Use this query
Select * from table1 where dbo.numericonly(id) = '" & txtid & "'

Related

How to compose T-SQL WHERE statement to determine whether the specific filter value is a power of 2 collectible from column values

I got SQL Table and column called MultiTypes (int).
MultiyTypes column values are regular numbers. I need to decompose those numbers to power-of-2 collectibles and then to check whether the filter value is one of these collectibles.
How to construct my WHERE Statement properly?
Example:
Column has values:
10 which is (8+2),
25 which is (16+8+1),
17 which is (16+1),
101 which is (64+32+4+1)
I want to build query
SELECT * FROM TABLE
WHERE #FilterValue -???-> MultiTypes
-???-> means - #FilterValue is one of the "power-of-2" collectibles of the iterated value
If filter value is 8, I will get rows with MultiTypes values 10 and 25
If filter value is 1, I will get rows with MultiTypes values 17, 101 and 25
If you want to know if a filter value matches a bit-array in the "1" positions, you use bitwise-and. It looks like:
where MultiType_Column & #filter = #filter
There is no need to decompose the value to specific types.
If you want to know if any of the values are set, then you can use:
where MultiType_Column & #filter <> 0
Generally to test if MultiTypes matches the combination of types, say Type2 + Type4 we do, pseudocode:
(MultiTypes <bit AND> (Type2 <bit OR> Type4)) == (Type2 <bit OR> Type4)
<bit AND> , <bit OR> are sql product specific, check your product's manuals.
Sql-server demo
declare #multitype int = 128 + 16 + 1;
declare #test int = 128 + 1;
declare #test2 int = 64 + 1;
select 'Yes, #multitype includes all types of #test' res
where #multitype & #test = #test;
select 'this will not return any row' res2
where #multitype & #test2 = #test2;
If you want to filter based on the type(k) (2^k), you can use & operator:
SELECT *
FROM table_name
WHERE (MultiyType_Column & (POWER(2,k)) <> 0
The above query gets all rows which have type(k). Fo example if k=3, to get all rows that have type3 you can do the following:
SELECT *
FROM table_name
WHERE (MultiyType_Column & (POWER(2,3)) <> 0
I think this cannot be resolved in a SQL query because the lack of arithmetic operations you can make in the query, my recommendation is to create a procedure and there you can divide the number the times that you need.

Replace every alpha character with itself + wildcard in string SQL Server

My goal is to create a query that will search for results related to a specific keyword.
Say in a database we had the word cat.
Regardless of if the user types C a t, C.A.T. or Cat I want to find a result related to the search as long as the alpha numeric characters are in the correct sequence that is all that matters
Say in the database we have these 4 records
cat
c/a/t
c.a.t
c. at
If the user types in C#$*(&A T I'd like to get all 4 results.
What I have written so far in my query is a function that strips any non-alphanumeric characters from the input string.
What can I do to replace each alphanumeric character with itself and add a wildcard at the end?
For every alpha character my input would look similar to this
C%[^a-zA-Z0-9]%A%[^a-zA-Z0-9]%T%[^a-zA-Z0-9]%
Actually, that search string will return only one record from this table: the row with 'c.a.t '.
This is because the expression C%[^a-zA-Z0-9]%A does not mean there can't be any alpha-numeric chars between C and A.
What it actually means is there should be at least one non alpha-numeric value between C and A.
Moreover, it will return incorrect values as well - a value like 'c u a s e t ' will be returned.
You need to change your where clause to something like this:
WHERE column LIKE '%C%A%T%'
AND column NOT LIKE '%C%[a-zA-Z0-9]%A%[a-zA-Z0-9]%T%'
This way, if you have cat in the correct order, the first row will resolve to true, and if there are no other alpha-numeric chars between c, a, and t the second row will resolve to true.
Here is a test script, where you can see for yourself what I mean:
DECLARE #T AS TABLE
(
a varchar(20)
)
INSERT INTO #T VALUES
('cat'),
('c/a/t'),
('c.a.t '),
('c. at'),
('c u a s e t ')
-- Incorrect where clause
SELECT *
FROM #T
WHERE a LIKE 'C%[^a-zA-Z0-9]%A%[^a-zA-Z0-9]%T%[^a-zA-Z0-9]%'
-- correct where clause
SELECT *
FROM #T
WHERE a LIKE '%C%A%T%'
AND a NOT LIKE '%C%[a-zA-Z0-9]%A%[a-zA-Z0-9]%T%'
You can also see it in action in this link.
And since I had some spare time, here is a script to create both the like and the not like patterns from the input string:
DECLARE #INPUT varchar(100) = '#*# c %^&# a ^&*$&* t (*&(%!##$'
DECLARE #Index int = 1,
#CurrentChar char(1),
#Like varchar(100),
#NotLike varchar(100) = '%'
WHILE #Index < LEN(#Input)
BEGIN
SET #CurrentChar = SUBSTRING(#INPUT, #Index, 1)
IF PATINDEX('%[^a-zA-Z0-9]%', #CurrentChar) = 0
BEGIN
SET #NotLike = #NotLike + #CurrentChar + '%[a-zA-Z0-9]%'
END
SET #Index = #Index + 1
END
SELECT #NotLike = LEFT(#NotLike, LEN(#NotLike) - 12),
#Like = REPLACE(#NotLike, '%[a-zA-Z0-9]%', '%')
SELECT *
FROM #T
WHERE a LIKE #Like
AND a NOT LIKE #NotLike
You can recursively go through your (cleaned) search string and to each letter add the expression you would like. In my example #builtString should be what you would like to use further on, if I understood correctly.
declare #cleanSearch as nvarchar(10) = 'CAT'
declare #builtString as nvarchar(100) = ''
WHILE LEN(#cleanSearch) > 0 -- loop until you deplete the search string
BEGIN
SET #builtString = #builtString + substring(#cleanSearch,1,1) + '%[^a-zA-Z0-9]%' -- append the letter plus regular expression
SET #cleanSearch = right(#cleanSearch, len(#cleanSearch) - 1) -- remove first letter of the search string
END
SELECT #builtString --will look like C%[^a-zA-Z0-9]%A%[^a-zA-Z0-9]%T%[^a-zA-Z0-9]%
SELECT #cleanSearch --#cleanSearch is now empty

Is there an SQL function that you can exclude results with integer and characters

I have a number of records in my results that follow the following format:
TJ12345
So, any 2 characters followed by a set of integers. Is there a way I can exclude these records from my results?
Other records within the results have all characters for at least the first three letters so;
tfydu734, fdsha21344, hdsifhsidufh2
SELECT name, Filername
FROM [Permissions] with (nolock)
WHERE (Name like '" & txtSearch.Text & "'
or ACEName like '" & txtSearch.Text & "')
and (ACEName not like '%Error%'
and ACEName not like '%nas_%'
and ACEName not like '%NASA%')
Thanks for any help
Well, task "determine if string contains two letters followed by digits" can be solved like:
declare #x nvarchar(max)
select #x = 'TJ12345'
select
case
when #x like '[A-z][A-z]%' and isnumeric(right(#x, len(#x) - 2)) = 1 then 1
else 0
end as Should_Be_Excluded
Key idea: first check if it starts with two letters, then strip them out and check if remaining string contains only digits using isnumeric fuction.
So literally you need to invert this criteria and put it into where condition in order to exclude these records.
select *
from your_table
where
your_field not like '[A-z][A-z]%'
or isnumeric(right(your_field, len(your_field) - 2)) = 0
Other records within the results have all characters for at least the first three letters
so you could simply use
WHERE ACEName LIKE '[A-z][A-z][A-z]%'

Zero or more occurrences of pattern matching in sql stored procedure

In my stored procedure, I want to set student ID pattern and further based on that pattern I want to retrieve data from table.
Student ID pattern should be like string STUD-, followed by 2 to 3 digits.
The pattern should have values from STUD-11 and STUD-125
For example: STUD-12 and STUD-123.
Currently I am using pattern as :
SET #stud_ID_like = 'STUD-[1-9][0123456789]'
But it accepts STUD-10 that I don't want.
And how can I get 3 digits after string STUD-.
For this if I use STUD-[1-9][0123456789][0123456789] pattern then how can I take 2 digit value like STUD-15.
Is there '*' wild card character in SQL for pattern matching so that I can use it for zero or more occurrences ? Or any other solution for this ?
My stored procedure is something like this:
stored procedure A
#stud_ID_like varchar(128)
AS
BEGIN
SET #stud_ID_like = 'STUD-[1-9][0123456789]'
BEGIN TRANSACTION
SELECT TOP 1 [Student Name]
FROM [Student_list_table]
WHERE [Result] = 'PASS' AND [St_ID] LIKE #stud_ID_like
COMMIT TRANSACTION
END
You can build or statements for the matches between STUD-11 and STUD-125
SELECT TOP 1 [Student Name]
FROM [Student_list_table]
WHERE [Result] = 'PASS'
AND [St_ID] LIKE 'STUD-1[1-9]'
OR [St_ID] LIKE 'STUD-[2-9][0-9]'
OR [St_ID] LIKE 'STUD-1[0-1][0-9]'
OR [St_ID] LIKE 'STUD-12[0-5]'
SQL Fiddle Example
Might be less trouble to pass in a min id and max id, then convert the value after STUD- to an int and compare that way.
CREATE PROC A (
#Min INT,
#Max INT
)
AS
BEGIN
SET #Min = 11
SET #Max = 125
SELECT TOP 1 [Student Name]
FROM [Student_list_table]
WHERE [Result] = 'PASS'
AND CONVERT(INT, SUBSTRING([St_ID], PATINDEX('%-%', [St_ID]) + 1, LEN([St_ID])))
BETWEEN #Min AND #Max
END
To meet the criteria as specified, you'd have to do 3 parts.
From the OP comment..
Except STUD-1 to STUD-10 , all other Values fromSTUD-11 to STUD-125 is
valid values for me. And main thing is how can I check zero or more
occurance so that I can use it for 3rd digit
WHERE
(
StudentID LIKE 'STUD-[1-9][0-9]'
AND
StudentID != 'STUD-10'
)
OR
(
StudentID LIKE 'STUD-[1-9][0-9][0-9]'
)
This will cover 11 - 999
You can continue nesting conditions like this if you want to forcibly exclude values >= 126, but it gets ugly. One of the other proposed answers takes a stab at it, but accidentally excluded all values over 100 that ended with a digit higher than 5.
This solution will not use index if any exists on StudentID column:
where replace(StudentID, 'STUD-', '') between 11 and 125

Modify int result of count in sql server 2005

I am working on sql server 2005 and I am taking count from a specific table
SELECT count(StudentIdReference) as studentCount FROM StudentTable
Right now this select statement is returning me result like 2 or 78 or 790. But in future it will grow rapidly and on UI I don't have sufficient space to show the digit like 1000000.
What I want that after 3 digit, I will get the number like 1K or 1.6K, just as we see on stackoverflow.
This would be simpler to be done in the Presentation Layer of your application.
You coud write a user function and do something like this....
CREATE FUNCTION prettyPrint
(#number int)
RETURNS varchar(30)
AS
BEGIN
declare #return varchar(30)
set #return = cast(#number as varchar(3))
if #number > 1000
set #return = ''+ cast((#number/1000) as varchar(3)) + '.' + cast((#number % 1000)/100 as varchar(3)) +'K'
-- here must be more 'exceptions' or change all this about the magic number 1000
return #return
end
select dbo.prettyPrint(1500)
SELECT prettyPrint(count(StudentIdReference)) as studentCount FROM StudentTable
As others have stated you should really be doing this in your Presentation Layer not at the DB, however, this will do it for you:
Declare #StudentCount int,
#StudentCountFormatted varchar(10)
Select #StudentCount = Count(StudentIdReference) as studentCount FROM StudentTable
If #StudentCount > 999
Begin
Select #StudentCountFormatted = Convert(Varchar(10), Convert(numeric(19,1), (#StudentCount/ 1000.00))) + 'K'
End
Else
Begin
Select #StudentCountFormatted = #StudentCount
End
Select #StudentCountFormatted
You need to write your own logic to show such text. There is no built-in method.
I would return the COUNT as-is from SQL Server and leave the formatting up to the UI. This is because:
1) usually easier/performant to do formatting/string manipulation outside of SQL
2) different places in your code using the same query may want to use the data in different ways (maybe not now, but could do in future) so returning the count as-is gives you that flexibility - i.e. won't need 1 version to return the count as an INT and another to return the same as a formatted VARCHAR
You could do it in SQL, but in general I believe in pushing this in to the UI as it's a display/formatting behaviour.
You can always try something like this
SELECT
CASE
WHEN len(cast(count(*) as varchar(10)))< 4 then cast(count(*) as varchar(10))
WHEN len(cast(count(*) as varchar(10)))> 4 and len(cast(count(*)as varchar(10)))< 7
THEN cast(cast(count(*) / 1000.0 as decimal(10,1)) as varchar(10)) + 'k'
ELSE cast(cast(count(*) / 1000000.0 as decimal(10,1)) as varchar(10)) + 'm'
END StudentCount
FROM StudentTable