Search half the refID in SQL - sql

I have a SQL table which hold unique REFID (int) and many other columns. I wanted to search a row using the half REFID . So if someone just search 0001 then 50001, 00015... comes up.
I have tried:
SELECT TOP 10 REFID
FROM Tablename
where REFID LIKE '%' + cast(0001 as varchar(10)) +'%'
however the problem is, it also giving me 150100 however I wanted 0001 to be in order.
'0001' is passed in as a parameter passed in from my C# application. I know I can convert the '0001' to string/varchar before sending it to the SQL however I was looking for a way to do it within the SQL so I can pass in the int from C# application

Code:
SELECT TOP 10 REFID
FROM Tablename
where REFID LIKE '%0001%'

0001 is a number and when converted to varchar() it will become '1'.
This will work with any number but only if you know beforehand that you will use four characters in your expression.
SELECT TOP 10 REFID
FROM Tablename
where REFID LIKE '%' + RIGHT('0000' + CAST(0001 AS VARCHAR(4)), 4) +'%'
We don't know how are you building your SQL statement, so we may need more information in order to help. Where do you get your ' 0001' value from? Is it a variable? Is it a parameter in a stored procedure? Is it inside a function in a different programming language?

You need to compare the REFID to a string value (not an int: as the comments point out, CAST(0001 AS VARCHAR(10)) returns 1, not 0001.
SELECT TOP 10 REFID
FROM Tablename
where REFID LIKE '%0001%'
EDIT: you have bigger issues too, like how to search for an integer value stored without leading zeroes, but if you are passing in a parameter you need to either make it varchar, or convert it to varchar in your query body, like so (assuming, of course, that you are always searching for a four-digit string):
SET #SearchParam_char = RIGHT('000' + CAST(#searchParam_Int AS VARCHAR(10)), 4)

I have found:
cast('0001' as varchar(10)) as 0001 === 1 thanks to ALEX K.
SQL will strip leading zero and there is no way of keeping the zero if you don't know the length.
My solution: I will send a string from my application and let SQL search it using the string.

Related

SQL Query to compare the first X characters of 2 fields in a table

Say I have a table named 'Parts'. I am looking to create a SQL query that compares the first X characters of two of the fields, let's call them 'PartNum1' and 'PartNum2'. For example, I would like to return all records from 'Parts' where the first 6 characters of 'PartNum1' equals the first 6 characters of 'PartNum2'.
Parts
PartNum1
PartNum2
12345678
12345600
12388888
12345000
12000000
14500000
the query would only return row 1 since the first 6 characters match. MS SQL Server 2017 in case that makes a difference.
If they are strings, use left():
left(partnum1, 6) = left(partnum2, 6)
This would be appropriate in a where, on, or case expression. Note that using left() would generally prevent the use of indexes. If this is for a join and you care about performance, you might want to include a computed column with the first six characters.
you can try something like this. I am assuming datatype as integer. You can set size of varchar based on length of fields.
select *
from Parts
WHERE SUBSTRING(CAST(PartNum1 AS VARCHAR(max)), 1,6) = SUBSTRING(CAST(PartNum2 AS VARCHAR(max)), 1,6)
You can go for simple division to see if the numerator matches for those partnumbers.
DECLARE #table table(partnum int, partnum2 int)
insert into #table values
(12345678, 12345600)
,(12388888, 12345000)
,(12000000, 14500000);
select * from #table where partnum/100 = partnum2/100
partnum
partnum2
12345678
12345600

Query to find if a column contains both number and decimal only

I have a column to check if contains number from 0-9 and a decimal. Since in the version of SQL am using the below does not seem working
select *
from tablename
whwere columnname like '%[^.0-9]%'
Also tried using column name like '%[0-9]%' and columnname not like '%.%' but if there is a negative sign it is not getting captured. Please advise.
The column data type is float. So can someone provide me a query to check if the column contains values from 0-9 and also it can contain decimal values these two are permitted. If say for example if I have value 9,9.99 ,-1.24 the query should output -1.24 I need this value other than decimal and number –
The issue with your LIKE clause is bad predicate logic ...like '%[^.0-9]%'should be NOT LIKE '%[^0-9.]%'
Take this sample data.
DECLARE #table TABLE (SomeNbr VARCHAR(32));
INSERT #table VALUES ('x'),('0'),('0.12'),('999'),('-29.33'),('88.33.22'),('9-9-'),('11-');
What you were trying to do would be accomplished like this:
SELECT t.someNbr
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.]%';
The problem here is we'll also return "88.33.22" and miss "-29.33", both valid float values. You can handle hyphens by adding a hyphen to your LIKE pattern:
SELECT t.someNbr, LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'.',''))
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.-]%';
But now we also pick up "9-9-" and stuff with 2+ dots. To ensure that each starts with a number OR a hyphen, to ensure hyphens only exist in the front of the string (if at all) and that we a maximum of one dot:
--==== This will do a good job but can still be broken
SELECT t.someNbr
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.-]%' -- Can only contain numbers, dots and hyphens
AND LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'.','')) < 2 -- can have up to 1 dot
AND LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'-','')) < 2 -- can have up to 1 hyphen
AND PATINDEX('%-%',t.SomeNbr) < 2 -- hyphen can only be in the front
This does the trick and returns:
someNbr
--------------------------------
0
0.12
999
-29.33
All that said - **DONT DO THIS ANY OF THIS ^^^ **. There is no need to parse numbers in this way except to show others why not to. I can still break this. They way I return valid floats in a scenario like this is with TRY_CAST or TRY_CONVERT. This returns what you need and will perform better.
--==== Best Solution
SELECT t.someNbr
FROM #table AS t
WHERE TRY_CAST(t.SomeNbr AS float) IS NOT NULL;

SQL Server - Combine string to integer where integer can have a variable number of leading zeros

I have a report in SQL Server Report Builder which brings back the profession acronym (string) and registration number (integer) for each professional in a separate SQL database.
The registration number can be 5 or more digits long, and may start with one or more zeros. For example:
Profession Registration #
AB 00162
PH 02272
SA 13925
SA 026025
DA 1025927
I'm trying to put the profession acronym and registration number together into a registration ID, because I need to compare this with the registration ID from another (non SQL) database.
I'm trying to get something like this:
Registration ID
AB00162
PH02272
SA13925
SA026025
DA1025927
I've tried converting the integers to strings using the following in my query:
REGISTRY.PROFESSION + right('00000' + cast(REGISTRY.REGISTRATION_NO as varchar(8)), 5) as Full_Reg_Number
However, with the above the integers that are more than 5 digits long get cut off, and if I increase '00000' to, say, '0000000' and the number '5' to '7' in the above, the integers that only have 5 digits are padded with extra leading zeros.
I do not have permission to change the formatting of the integers in either database.
Integers aren't stored with leading zeroes. To be stored like that, then the field is NOT of integer type in the first place. Simply do:
Registry.profession + registry.registration_no
You can confirm that the stored type is not an integer as follows:
select data_type
from information_schema.columns
where table_name = 'registry'
and column_name = 'registration_no'
If you're getting a type conversion error as you mention in your comments, then most likely the error is not coming due to this concatenation. It's probably down the line, such as if you're using 'Full_Reg_Number' in a 'where' statement or other comparison that expects a comparison to an integer, and instead is getting a varchar. After all, you called the column 'Full_Reg_Number' even though it's not a number.
Based on your problems, I suspect those really are integers. You've just shown them with leading zeros in the question.
A simple solution is to use case:
(REGISTRY.PROFESSION +
CASE WHEN REGISTRY.REGISTRATION_NO < 10000 THEN right('00000' + cast(REGISTRY.REGISTRATION_NO as varchar(8)), 5)
ELSE REGISTRY.REGISTRATION_NO
END
) as Full_Reg_Number
An even simpler method uses FORMAT():
(REGISTRY.PROFESSION + FORMAT(REGISTRY.REGISTRATION_NO, '00000')
) as Full_Reg_Number

Google Style Search Suggestions with Levenshtein Edit Distance

Ok guys working on search suggestions using jQuery-UI AutoComplete with results from sql-sever 2008 db. Using AdventureWorks DB Products table for testing. I want to search across 2 fields in this example. ProductNumber and Name.
I asked 2 questions earlier relating to this...here and here
and ive come up with this so far...
CREATE procedure [dbo].[procProductAutoComplete]
(
#searchString nvarchar(100)
)
as
begin
declare #param nvarchar(100);
set #param = LOWER(#searchString);
WITH Results(result)
AS
(
select TOP 10 Name as 'result'
from Production.Product
where LOWER(Name) like '%' + #param + '%' or (0 <= dbo.lvn(#param, LOWER (Name), 6))
union
select TOP 10 ProductNumber as 'result'
from Production.Product
where LOWER(ProductNumber) like '%' + #param + '%' or (0 <= dbo.lvn(#param, LOWER(ProductNumber), 6))
)
SELECT TOP 20 * from Results
end;
My problem now is ordering of the results...I am getting the correct results but they are just ordered by the Name or product number and are not relevant to the input string...
for example I can search for product Number starting with "BZ-" and the top returned results are ProductNums starting with "A" although I do get more relevant results elsewhere in the list..
any ideas for sorting the results in terms of relevance to the search string??
EDIT:
in regards to the tql implementation of the levenschtein distance found here(linked to in previous question)...
I am wondering what would be the best way to determine the MAX value to send to the function (6 in my example above)
Would it be best to choose an arbitrary value based on what "seems" to work well for my given data set? or would it be best to adjust it dynamically based on the length of the input string...
My initial thoughs were that the value to should be inverely proportional to the length of the searchString...so as the search string grows and becomes more specific..the tolerance decreases...thoughts??
The Full Text Search feature seems to be the way go when using SQL Server
The relevance is the result of dbo.lvn(). It returns the amount of operations need to transform one string into the other. So the answer is simple:
ORDER BY dbo.lvn(#param, LOWER (Name), 6)
But this won't work in combination to the LIKE as this does not return any relevance value. But the usage of LIKE is not a good idea at all. If someone is tiping "tooth" to buy "toothpaste" he would get "bluetooth" as proposal.
To make devlim faster read here:
https://stackoverflow.com/a/14261807/318765

How to generate alphanumeric tokens in SQL Server?

I am looking to generate soem alpha numeric tokens. Is there a function that can do to generate set length tokens?
You can do this and then take a substring of it of whatever length you need:
select replace(newid(), '-', '')
E.g., for eight characters:
select substring(replace(newid(), '-', ''), 1, 8)
I have done this by combining a unique id from the table with a random number:
update [table]
set token = cast([id] as varchar(10)) + cast(cast(round((rand() * 500000000.0), 0) as int) as varchar(10))
Adjust the varchar sizes and the multiplication factor to get the toekn size you need. If you need a precise size, make the resulting string a little too long and use substring to set the length.
This is not crytographically strong, but it works for me in most cases. Using the id field from the table guarantees that the token is unique, and the random number makes it difficult to guess.
Another possible solution (for SQL Server, i think NEWID() is not available in other DBMS but use another similar function):
SELECT CONVERT(VARCHAR(10), RIGHT(NEWID(), 5))
The NEWID() function returns a Alpha numeric ID generated by SQL Server which you can use in the way you need.
Works well for me.