2017-01-06 8 views
0

У меня есть этот выберите сценарий:Как достичь эквивалента «оценок короткого замыкания» в T-SQL

Я хотел бы вернуться точных матчами первого, то проверяет только для частичного совпадения постепенно, используя простой запрос T-sql.

select * from accounts where 
    mobile = @mobile or 
    mobile like @mobile +'%' or 
    mobile like '%'[email protected] or 
    mobile like '%'[email protected] +'%' 

Я понимаю, что T-sql выполняет All-At-Once операций.

Как лучше всего это достичь?

+1

SQL Server не поддерживает оценки BOOL «короткого замыкания», и нет никакой возможности, чтобы «включить его» либо .. .. –

+0

@marc_s Вот почему я спрашиваю, как мы можем достичь * эквивалента * короткого замыкания, где статья –

ответ

4

Вы могли бы оценить в случае и ранжируют значения:

select 
    mobile, 
    case 
    when mobile = @mobile    then 1 
    when mobile like @mobile +'%'  then 2 
    when mobile like '%'[email protected]  then 3 
    when mobile like '%'[email protected] +'%' then 4 
    end as [Rank] 
from accounts where 
    mobile = @mobile or 
    mobile like @mobile +'%' or 
    mobile like '%'[email protected] or 
    mobile like '%'[email protected] +'%' 
order by [Rank] 
+0

Это решение не создает дубликат, как ** union ** solution. Спасибо –

+2

Он также не пересекает исходную таблицу кучу раз. Добавьте запрос внешнего фильтра, и он делает то же самое, что и я. –

+0

Я получаю то, что вы делаете, и я согласен, что это правильно и предпочтительное решение с точки зрения набора, но это не очень короткое замыкание, так как оно, скорее всего, пройдет по всей таблице, по крайней мере один раз. –

2

Один из способов сделать это - разделить запрос на несколько запросов. Я не говорю, что это дает лучшую производительность, но:

select * from accounts 
where mobile = @mobile 

union 

select * from accounts 
where like @mobile +'%' 
    and not exists (select 1 from accounts where mobile = @mobile) 

union 

select * from accounts 
where mobile like '%'[email protected] 
    and not exists (select 1 from accounts where like @mobile +'%') 

union 

select * from accounts 
where mobile like '%'[email protected] +'%' 
    and not exists (select 1 from accounts where like '%'[email protected]) 

Что-то другое, что вы можете сделать, что более «programatic» является использование @@ROWCOUNT, что должно дать более высокую производительность, так как он имитирует короткое замыкание.

select * from accounts 
where mobile = @mobile 

if @@rowcount = 0 
    select * from accounts 
    where like @mobile +'%' 

if @@rowcount = 0 
    select * from accounts 
    where mobile like '%'[email protected] 

if @@rowcount = 0 
    select * from accounts 
    where mobile like '%'[email protected] +'%' 
+0

, и это из-за операции «все в один раз»? –

+3

@CharlesOkwuagwu Ну, сначала вам нужно понять, что SQL - это декларативный язык, вы не говорите ему, как это делать, вы просто говорите ему, как вы хотите получить результат, и он получит его для вас. Позвольте мне посмотреть, могу ли я найти сообщение в блоге, которое объясняет это более подробно. Я сделал несколько «короткое замыкание», где на самом деле я разбил его на отдельные запросы. Первый будет работать сам по себе, затем 2-й, затем 3-й и 4-й, но, начиная со второго запроса, у них есть дополнительное условие, основанное на IF, в котором предыдущий запрос возвращал любые результаты. –

+0

Вариант с @@ rowcount блистателен. Спасибо –

 Смежные вопросы

  • Нет связанных вопросов^_^