In my table there are codes which are basically decimal values. For example the code column contains data like 001.0, 00.10, 002.0, 00.20 etc. I have to write a SQL query which shows following result while searching the code values from UI:
If the user searches 0010, I have to show all the values 001.0, 00.10
if the user searches 001.0, I have to show values like 001.0, 001.1 etc.
if the user searches 00.10, I have to show value 00.10, 00.12 etc.
Please help me in writing SQL query for the above criteria.
Not everything is entirely clear about your rules, but I hope that the following will serve you as a passable starting point at least.
Apparently, the search term should be processed in two ways, depending on whether it contains the decimal point. So first you need to know whether the point is present or not. That could be done using the CHARINDEX() function: if it returns 0, the decimal point is absent from the search term, otherwise it is there. Thus, your complete condition will be structured like this:
WHERE CHARINDEX('.', #SearchTerm) = 0 AND … /* condition to match '0010'-like input */
OR CHARINDEX('.', #SearchTerm) > 0 AND … /* condition to match input containing '.' */
The condition to search for the term without . might look like this:
REPLACE(Code, '.', '') = #SearchTerm /* or maybe LIKE #SearchTerm + '%'? */
The condition for the case when the search term does contain . seems to me trickier than the previous one, but anyway, here's what I came up with:
Code LIKE REPLACE(RTRIM(REPLACE(#SearchTerm, '0', ' ')), ' ', '0') + '%'
How it works, step by step, using '001.0' and '00.10' as examples:
Initial value '001.0' '00.10'
REPLACE(#SearchTerm, '0', ' ') ' 1. ' ' .1 '
RTRIM(REPLACE(#SearchTerm, '0', ' ')) ' 1.' ' .1'
REPLACE(RTRIM(REPLACE(#SearchTerm, '0', ' ')), ' ', '0') '001.' '00.1'
REPLACE(RTRIM(REPLACE(#SearchTerm, '0', ' ')), ' ', '0') + '%' '001.%' '00.1%'
So, as you can see, the expression evaluates to a mask that should satisfy your rules for search terms containing ..
Pulling all the conditions together, we get the following WHERE clause:
WHERE CHARINDEX('.', #SearchTerm) = 0 AND REPLACE(Code, '.', '') = #SearchTerm
OR CHARINDEX('.', #SearchTerm) > 0 AND
Code LIKE REPLACE(RTRIM(REPLACE(#SearchTerm, '0', ' ')), ' ', '0') + '%'
Related
I am a bit new to this site but I have looked an many possible answers to my question but none of them has answered my need. I have a feeling it's a good challenge. Here it goes.
In one of our tables we list what is used to run a report this can mean that we can have a short EXEC [svr1].[dbo].[stored_procedure] or "...From svr1.dbo.stored_procedure...".
My goal is to get the stored procedure name out of this string (column). I have tried to get the string between '[' and ']' but that breaks when there are no brackets. I have been at this for a few days and just can't seem to find a solution.
Any assistance you can provide is greatly appreciated.
Thank you in advance for entertaining this question.
almostanexpert
Considering the ending character of your sample sentences is space, or your sentences end without trailing ( whether space or any other character other than given samples ), and assuming you have no other dots before samples, the following would be a clean way which uses substring(), len(), charindex() and replace() together :
with t(str) as
(
select '[svr1].[dbo].[stored_procedure]' union all
select 'before svr1.dbo.stored_procedure someting more' union all
select 'abc before svr1.dbo.stored_procedure'
), t2(str) as
(
select replace(replace(str,'[',''),']','') from t
), t3(str) as
(
select substring(str,charindex('.',str)+1,len(str)) from t2
)
select
substring(
str,
charindex('.',str)+1,
case
when charindex(' ',str) > 0 then
charindex(' ',str)
else
len(str)
end - charindex('.',str)
) as "Result String"
from t3;
Result String
----------------
stored_procedure
stored_procedure
stored_procedure
Demo
With the variability of inputs you seem to have we will need to plan for a few scenarios. The below code assumes that there will be exactly two '.' characters before the stored_procedure, and that [stored_procedure] will either end the string or be followed by a space if the string continues.
SELECT TRIM('[' FROM TRIM(']' FROM --Trim brackets from final result if they exist
SUBSTR(column || ' ', --substr(string, start_pos, length), Space added in case proc name is end of str
INSTR(column || ' ', '.', 1, 2)+1, --start_pos: find second '.' and start 1 char after
INSTR(column || ' ', ' ', INSTR(column || ' ', '.', 1, 2), 1)-(INSTR(column || ' ', '.', 1, 2)+1))
-- Len: start after 2nd '.' and go until first space (subtract 2nd '.' index to get "Length")
))FROM TABLE;
Working from the middle out we'll start with using the SUBSTR function and concatenating a space to the end of the original string. This allows us to use a space to find the end of the stored_procedure even if it is the last piece of the string.
Next to find our starting position, we use INSTR to search for the second instance of the '.' and start 1 position after.
For the length argument, we find the index of the first space after that second '.' and then subtract that '.' index.
From here we have either [stored_procedure] or stored_procedure. Running the TRIM functions for each bracket will remove them if they exist, and if not will just return the name of the procedure.
Sample inputs based on above description:
'EXEC [svr1].[dbo].[stored_procedure]'
'EXEC [svr1].[dbo].[stored_procedure] FROM TEST'
'svr1.dbo.stored_procedure'
Note: This code is written for Oracle SQL but can be translated to mySQL using similar functions.
I tried to categorized the comment with keyword in SQL Server but I don't know how to get a specific string.
The word I need is ice only, but with the code '%ice%' I will get 'notice', 'service'...
SELECT
comment,
(CASE WHEN comment LIKE '%ice%' THEN 'Ice' END) AS comment_category
FROM events
Any suggestion on how to solve this?
If comment consists of words separated by spaces, you can do:
' ' + comment + ' ' like '% ice %'
You can even add other delimiters, such as:
' ' + comment + ' ' like '%[- ,.()]ice[- ,.()]%'
You can also use SQL Server's kinda sorta regex:
'.' + comment + '.' like '%[^a-z0-9]ice[^a-z0-9]%'
There are a lot of posts on how to split a single column value into multiple columns, however I am having trouble standardizing data in the column to be able to use those techniques. What is the best approach for standardizing the below example?
For example:
**emails**
first_email,second_email
third_email; fourth_email
fifth_email ;sixth_email
seventh_email, eight_email
ninth_email.tenth_email
My expected output from standardization is:
**emails**
first_email, second_email
third_email, fourth_email
fifth_email, sixth_email
seventh_email, eight_email
ninth_email, tenth_email
This shows how you can normalize the formatting, but because the . character is sometimes used in an email address and other times used to separate email addresses, you should probably not include the replace for the ., and just work through those manually.
You can used a nested replace() to eliminate the spaces first, then replace the valid email address separators with ,[space].
declare #str varchar(max) = 'first_email,second_email
third_email; fourth_email
fifth_email ;sixth_email
seventh_email, eight_email
ninth_email.tenth_email'
select replace(replace(replace(replace(
#str, ' ', ''), -- a space is not valid in an email
',', ', '),
';', ', '),
'.', ', '
)
Which returns:
first_email, second_email
third_email, fourth_email
fifth_email, sixth_email
seventh_email, eight_email
ninth_email, tenth_email
I am looking to subtract two string columns from another string column.
I have acheived this in the past in Oracle using the below
SELECT
C.MANUFACTURER,
C.MODEL_GROUP,
REGEXP_REPLACE(C.VARIANT, '^'||C.MANUFACTURER || ' +' || C.MODEL_GROUP) "VAR DESC",
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C
I now need to acheive the same in MS SQL any suggestions would be appreciated.
"Subtract" is surely a misnomer here. The OP appears to want to remove a string at the beginning of another string.
From this point on, I am assuming that MANUFACTURER and MODEL_GROUP do not contain any regular expression wildcard characters.
There is a challenge with multiple spaces. If there are not too many, then you can do. For instance, this handles one or two spaces:
SELECT C.MANUFACTURER, C.MODEL_GROUP,
(CASE WHEN C.VARIANT LIKE C.MANUFACTURER + ' ' + C.MODEL_GROUP + '%'
THEN STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER + ' ' + C.MODEL_GROUP), '')
WHEN C.VARIANT LIKE C.MANUFACTURER + ' ' + C.MODEL_GROUP + '%' AND
THEN STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER + ' ' + C.MODEL_GROUP), '')
ELSE C.VARIANT
END) as [VAR DESC],
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C;
EDIT:
Here is a more complete solution:
SELECT C.MANUFACTURER, C.MODEL_GROUP,
(CASE WHEN C.VARIANT LIKE C.MANUFACTURER + ' %' + C.MODEL_GROUP + '%' AND
C.VARIANT NOT LIKE C.MANUFACTURER + ' %[^ ]%' + C.MODEL_GROUP + '%'
THEN STUFF(LTRIM(STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER), '')), 1, LEN(C.MODEL_GROUP), '')
ELSE C.VARIANT
END) as [VAR DESC],
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C;
This tests for just spaces between the two strings (the not like is checking for something other than a space). The replacement is then in three steps -- remove the manufacturer, then the spaces, then the model group.
I have spent some time on this one as much for my own satisfaction and in addition to the answer above, I have come up with the following which also generates the correct answer.
SUBSTRING(FV.VARIANT, LEN(FV.MANUFACTURER + ' ' + FV.MODEL_RANGE + ' ') + 1 , LEN(FV.VARIANT))
My problem was kinda easier to solve, I just needed to remove "xxxx" (the first 4 characters) at the start of a column from some rows:
UPDATE coluna SET columToEdit = SUBSTRING(columToEdit, 5, 200);
I've tried select REPLACE(' this is a user name', ' ', '') and it gives me 'thisisausername' which is supposed to be.
My problem is, when I try to use REPLACE on selecting a table column, it doesn't work!
My query:
SELECT REPLACE(UserName, ' ', '') as UserName FROM MY_TABLE
it still gives me usernames with spaces! Am I doing something stupid?
#AlexK. it's 160 for unicode(left(field, 1))
160 is Unicode NO-BREAK SPACE so that's what you need to replace:
replace(UserName, char(160), '')
You could update everything replacing char(160) with a whitespace ' ' and then just use your original query in the future (perhaps also ensuring such values cannot be entered in the future)