WHERE clause based on part of a VARCHAR column - sql

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

Related

SQL String - remove a substring between 2 occurences

I have some strings like :
0#11001#2017#308
0#1#2018#327
0#200510#2020#3022
I need to remove the year value (between last 2 '#').
So the results should be like :
0#11001#308
0#1#327
0#200510#3022
Is there a simple query to do it?
UPDATE
yourTable
SET
col = STUFF(yourTable.col, AtSign2.pos, atSign3.pos - atSign2.pos, '')
FROM
yourTable
OUTER APPLY
(SELECT CHARINDEX('#', yourTable.col, 0)) AS atSign1(pos)
OUTER APPLY
(SELECT CHARINDEX('#', yourTable.col, atSign1.pos+1)) AS atSign2(pos)
OUTER APPLY
(SELECT CHARINDEX('#', yourTable.col, atSign2.pos+1)) AS atSign3(pos)
The best thing to do here would be to normalize your data, and stop storing multiple data points embedded in a single string, in a single column. That being said, if you must proceed, we can try using the base string functions to splice together the update:
UPDATE yourTable
SET col = LEFT(col, CHARINDEX('#', col, CHARINDEX('#', col) + 1)) +
REVERSE(LEFT(REVERSE(col), CHARINDEX('#', REVERSE(col)) - 1));
Demo
Note that this answer assumes that every record would have three # separators in it. If not, then we would have to add additional logic.
DECLARE #STRING VARCHAR(50) = '0#200510#2020#3022'
DECLARE #NEED_TO_REMOVE VARCHAR(50) = PARSENAME(REPLACE(#STRING,'#','.'),2) + '#'
SELECT REPLACE(#STRING,#NEED_TO_REMOVE,'') --result: 0#200510#3022

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%

SQL Select, how to display numeric as money and reverse - numbers to positive

I have a numeric column formatted that contains data like:
8547.22
-1254.22
For reasons beyond my control I need to present the results of a select in this format (this is one field of a much larger select statement) I can't add any new functions either.
-$8,547.22
$1,254.22
So to be clear I need to add money formatting ('$' and ',') and also reverse positive numbers to negative and vice versa.
I've tried the following which obviously doesn't work:
case
when a.principal_outstanding like '-%'
then '$' + (SELECT RIGHT(REPLACE(CONVERT(varchar(20), (CAST(SUM(a.principal_outstanding) AS money)), 1), '.00', ''), LEN((REPLACE(CONVERT(varchar(20), (CAST(SUM(a.principal_outstanding) AS money)), 1), '.00', '')))) - 1)
when a.principal_outstanding not like '-%'
then '-' + '$' + (REPLACE(CONVERT(varchar(20), (CAST(SUM(a.principal_outstanding) AS money)), 1), '.00', ''))
else 'ERROR2'
end as '<currentBalance>'
Any suggestions?
If you must do this in your SQL query (and not the client):
SELECT '$' + CONVERT(VARCHAR, CAST(TheValue * -1 AS MONEY), 1)
FROM TheTable
Edit: Since you're using negative numbers, it gets even more ugly, but does the job.
SELECT CASE WHEN TheValue <= 0
THEN '$' + CONVERT(VARCHAR, CAST(TheValue * -1 AS MONEY), 1)
ELSE '-$' + CONVERT(VARCHAR, CAST(TheValue AS MONEY), 1)
END
FROM TheTable

SQL search issue

I know this is a simple question but here it goes. I've created a search button in Visual Studio using an SQL Statement. It works for first name and last name, but I also want it to search int such employee Id's. Here is the code :
SELECT ID, fName, lName, Discription, Box
FROM tb1
WHERE (fName LIKE '%' + #fName + '%') OR (lName LIKE '%' + #lName + '%') OR (ID LIKE '%' + #ID + '%')
When I test it, I get the error :
"Conversion failed when converting the varchar value '%' to data type int.
ID LIKE '%' + #ID + '%'
ID is an integer, '%' + #ID + '%' is a string. It can't really compare. An integer either is a value or it isn't. The % wildcards wouldn't mean anything to an integer.
I'm assuming what you want to do is convert the integer into a string so that you can match substrings of it. So, for example, searching for "1" would match on any integer which contains a "1" (10, 11, 12, 451, etc.). To do that you should simply need to convert the integer value to a string value in the WHERE clause:
(CAST(ID AS varchar(10)) LIKE '%' + #ID + '%'
(This assumes that your integer will never be more than 10 characters long. Adjust that value as necessary.)
You cannot use LIKE with integers, so you will have to convert the ID to varchar.
To convert you can use CAST or CONVERT:
http://msdn.microsoft.com/en-us/library/ms187928.aspx
Ex:
CAST(ID as varchar)
Your query:
SELECT ID, fName, lName, Discription, Box
FROM tb1
WHERE (fName LIKE '%' + #fName + '%') OR (lName LIKE '%' + #lName + '%') OR (CAST(ID as varchar) LIKE '%' + #ID + '%')
The LIKE syntax is compatible only with character-associated data types. INT types do not fall under this category.
Reference: http://msdn.microsoft.com/en-us/library/ms179859.aspx

SQL involving columns with comma delimited strings and comparison

I am updating the requirement..Basically A string can have 2 or 3 or 4 decimal places decimal places instead of the two decimal places as show below.
Suppose I have a record with a comma delimited strings in a column name "Version"
Say we have a record (A) containing having these values in its "Version" column
Version=10.1.2.4, 10.4.3.4,11.6.0, (the column has comma delimited strings)
I am passing an sql parameter called #VersionCheck
IF #VersionCheck = 11.6.0 and Version does not have any value like 11.5.6 (Note the 11 matches with the 11 in 11.6.0)
I want to return the record
So here are some examples all comparing with the parameter #VersionCheck= 11.6.0
Version=10.1.2,10.4.3.45 return this record
Version=10.1.2,10.4.3,10.4.4.5,11.6.0 return this record (if we have a match 11.6.0 and there are no strings starting with 11.something that is not equal to 11.6.0(parameter passed) we return this record)
Version= 10.1.2,10.4.3,11.6.0.2 do not return this record (to check, take the string before the first decimal point, in this case is 11, however 11.6.0.2 and 11.6.0 is not the same so it should not match)
How do I write the sql query to have this logic in the where clause?
If the parameter passed is #VersionCheck = 10.6.8 I do not want it to match if the strings in the comma delimited column has say 10.5.4 Basically take the characters before the first decimal and if they are equal (10=10), the rest of its values have to be the same else it should not match.
This is my solution below in sql server 2008 syntax
Note that #SU_Version is my parameter
and SuVersion.fieldValue is the column which has the comma delited string values like 10.1.2,10.3.4 etc
WHERE (CASE WHEN '%#SU_Version%' <> '' AND suVersion.fieldValue LIKE LTRIM('#SU_Version')
THEN suVersion.fieldValue
ELSE '%'
END like CASE WHEN '%#SU_Version%' <> ''
THEN '%#SU_Version%'
ELSE '%'
END
AND
(CASE WHEN LTRIM('#SU_Version') <> '' AND suVersion.fieldValue LIKE SUBSTRING(LTRIM('#SU_Version'),1, CHARINDEX( '.',LTRIM('#SU_Version'))-1)
THEN suVersion.fieldValue
ELSE'%'
END not like CASE WHEN LTRIM('#SU_Version')<> ''
THEN SUBSTRING(LTRIM('#SU_Version'),1, CHARINDEX( '.',LTRIM('#SU_Version'))-1) + '%'
ELSE '%'
END
AND
CASE WHEN LTRIM('#SU_Version') <> '' AND suVersion.fieldValue LIKE SUBSTRING(LTRIM('#SU_Version'),1, CHARINDEX( '.',LTRIM('#SU_Version'))-1)
THEN suVersion.fieldValue
ELSE'%'
END not like CASE WHEN LTRIM('#SU_Version')<> ''
THEN SUBSTRING(LTRIM('#SU_Version'),1, CHARINDEX( '.',LTRIM('#SU_Version'))-1) + '%'
ELSE '%'
END)
)
Since your design basically thwarts any attempts to use an index on the Version column anyway, this will give you rows where there is an exact match
...
WHERE ',' + Version + ',' LIKE '%,' + #VersionCheck + ',%'
For the funky requirements you have, try this (this assumes all version strings will contain exactly two decimal places):
DECLARE #v TABLE(Version VARCHAR(MAX));
INSERT #v SELECT ('10.1.2,10.4.3')
UNION ALL SELECT ('10.1.2,10.4.3,11.6.0')
UNION ALL SELECT ('10.1.2,10.4.3,11.5.2');
DECLARE #SU_Version VARCHAR(32);
SET #SU_Version = '11.6.0';
DECLARE
#p1 VARCHAR(10),
#p2 VARCHAR(10);
SELECT
#p1 = PARSENAME(#SU_Version, 3),
#p2 = PARSENAME(#SU_Version, 2);
SELECT Version = SUBSTRING(Version, 2, LEN(Version)-2) FROM
(
SELECT Version = ',' + Version + ',' FROM #v
) AS v WHERE
(
Version LIKE '%,' + #SU_Version + ',%'
OR
Version NOT LIKE '%,' + #p1 + '.%,%'
AND NOT
(
Version LIKE '%,' + #p1 + '.%,%'
AND
Version NOT LIKE '%,' + #p1 + '.' + #p2 + '.%,%'
)
);