SQL Server string left matching

Source: Internet
Author: User

In SQL Server, where fuzzy matching strings are often used, the simplest way is to use the LIKE keyword (like syntax http://msdn.microsoft.com/en-us/library/ms179859.aspx). But if we use the method of adding percent before and after, there is no way to use the index for fast query, so in many cases we use the left matching way. The most common example is in the search box, the user entered a part of the keyword, the system can be the user input to the left to match, to find out the relevant results listed. The advantage of using a left match is that you can use the index established in SQL Server to make the query efficient, but bad SQL statements still cause the index to become unusable.

Suppose we now have a table Ycmrsale, where there is a field Matnr store the material number information, if we want to query from this table with AB starting with the material number, if the use of nhibernate, then we commonly used to:

//queryover notation  var result = session. Queryover<ycmrsale> (). Whererestrictionon (c = c.matnr). Islike ( "AB" , Matchmode.start). List<ycmrsale> (); //linq to NHibernate  result = Session. Query<ycmrsale> (). Where (c = c.matnr.startswith ( "AB" )). ToList (); //criteria syntax  result = session. Createcriteria<ycmrsale> (). ADD (Expression.like ( "MATNR" ,  "AB" , Matchmode.start)). List<ycmrsale> (); 

These kinds of writing are essentially generated by the following where condition statement:

where  like ' ab% '

If you use EntityFramework, then the C # code of the query is similar to NHibernate:

var result = BwEntities.YCMRSALEs.Select (s = = S.matnr). Where (s = = S.startswith ("AB"));

The Where condition is the same:

WHERE  like ' ab% '

Here is only the simplest case, if we want to query the material number itself contains%, such as to query the "%00" the beginning of the material number, then how to ensure that the percent here is a percent sign rather than the meaning of fuzzy matching?

Using EntityFramework is simple and requires no modification, and the system generates different SQL statements based on the incoming string:

var result = BwEntities.YCMRSALEs.Select (s = = S.matnr). Where (s = = S.startswith ("%00"));

Generated SQL WHERE Condition:

WHERE  like ' ~%00% ' ESCAPE ' ~ '

For developers, it's really simple, no input. But if the use of nhibernate will be troublesome, we have to determine whether the user input string inside a special transfer character, if there is, then need to replace, and C # query statements are different.

string "%00"; Regex regex=New regex (@ "[~%\[\]_]" "delegatereturn" ~ " + M.value;}); var result = session. Queryover<ycmrsale> (). Whererestrictionon (c = c.matnr). Islike (input, Matchmode.start,' ~ '). List<ycmrsale> ();
Generated SQL WHERE Condition:
WHERE  like Escape ' ~ ' ' ~%00% '

All of this is done in the Ormapping tool to make a left-matching query, if we want to query the SQL statement directly, there is a way to do is to use the right-hand function. Also in the Ycmrsale table example, if we have another table Matnr, the MATNR column in the table stores an incomplete material number, now need to join two tables, using the MATNR column for the left match, then our SQL can be written as:

Select * from Ycmrsale sinnerjoin matnr mto Left (S.matnr,len ( M.MATNR)) =m.matnr

This can get the result we want, but because the function is used for the MATNR column, the index cannot be used, so the query is slow.

If we want to rewrite the form like, then we need to work on the Matnr column in the MATNR table, replace the special characters, and replace the words nonalphanumeric ~%_[]. So our SQL query will turn out like this:

Select * from Ycmrsale sinnerjoins matnr m on like replace (replace (Replace (replace (M.MATNR,' ~ ',' ~ ~ '),' _ ',' ~_ '),' [',' ~['),'] ',' ~] '),'% ', '~% ') +'% 'escape  ' ~ '

Although the SQL here looks more ugly, it can use the index set on the Ycmrsale table on the MATNR, so it is more efficient.

In addition to the handling of the keyword escape, Microsoft has also given another solution, which is to use "[]" to enclose the escaped character. This is simpler than the escape keyword, and the corresponding SQL is:

select  *from  ycmrsale S inner  join  matnr mon  s.matnr like  replace ( Replace (replace (m.matnr,, ),  ' [' , ),  '% ' ,  ' [%] ' ) + 

We can even write a custom function to deal with the transfer character in the case of join, which is very complicated ...

Create functionOPSTR (@input varchar(50))returns varchar(100) asbeginDeclare@iint= 1;Declare@result varchar(100) ="';Declare@cChar(1) while(@i<=len (@input))begin    Set@c=substring(@input, @i,1);if(@c=' [' or@c='% ' or@c=' _ ')begin        Set@result+=' ['[Email protected]+'] ';End    Else    begin        Set@result[Email protected];End    Set@i+=1;Endreturn@resultEnd
The custom function is then called in the query.
Select * from Ycmrsale sinnerjoins matnr m on like dbo. Opstr (M.MATNR) +'% '
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.