2014-12-19 3 views
2

В этом примере запрос (против плохо спроектированной базы данных о поставщиках):Перемещение IF EXISTS к ИНЕКЕ

DECLARE @OrderNo AS CHAR(8) = LEFT(@FullOrderNo,8) 

IF EXISTS (SELECT 1 FROM Foo WHERE FullOrderNumber = @FullOrderNo) 

    SELECT Stuff 
    FROM Foo 
    WHERE X = 'Y' 
      AND FullOrderNumber = @FullOrderNo 

    ELSE 

    SELECT Stuff 
    FROM Foo 
    WHERE X = 'Y' 
      AND OrderNumber = @OrderNo 

Поскольку Selects и первые участки ИНЕКЕ идентичны, есть способ, чтобы безопасно совместить запросы , проверяя, что совпадения FullOrderNumber сначала проверяются? Я видел, что есть no guarantees for WHERE clause evaluation order.

+0

'WHERE FullOrderNumber = @FullOrderNo OR OrderNumb er = @ OrderNo' –

+0

@ M.Ali: Это приведет к возврату 'OrderNumber = @ OrderNo' ненужных записей, когда есть записи, где' FullOrderNumber = @ FullOrderNo' – Gerrat

+0

@ M.Ali Я хочу только совместить номер OrderNumber, если нет совпадений FullOrderNumber в любом месте таблицы. – TrueWill

ответ

3

Вы можете написать это как:

SELECT Stuff 
FROM Foo 
WHERE X = 'Y' AND 
     (FullOrderNumber = @FullOrderNo OR 
     (NOT EXISTS (SELECT 1 FROM Foo WHERE FullOrderNumber = @FullOrderNo) and OrderNumber = @OrderNo)) 

Если вы ищете только одну строку, вы можете использовать order by приоритезации:

SELECT TOP (1) Stuff 
FROM Foo 
WHERE X = 'Y' AND 
     (FullOrderNumber = @FullOrderNo OR OrderNumber = @OrderNo) 
ORDER BY (CASE WHEN FullOrderNumber = @FullOrderNo THEN 1 ELSE 2 END) 

На самом деле, даже если есть дубликаты, вы можете используйте with ties следующим образом:

SELECT TOP (1) WITH TIES Stuff 
FROM Foo 
WHERE X = 'Y' AND 
     (FullOrderNumber = @FullOrderNo OR OrderNumber = @OrderNo) 
ORDER BY (CASE WHEN FullOrderNumber = @FullOrderNo THEN 1 ELSE 2 END) 
+2

Эти примеры могут переписать два оператора как одно; но они не застрахованы: «Сначала проверены совпадения FullOrderNumber». Если есть индекс в FullOrderNumber, но ни один из OrderNumber, возможно, что он может выполнить полное сканирование таблицы (что, по-видимому, OP пытается избежать с этим требованием). – Gerrat

+0

@Gerrat. , , Я интерпретировал это как «сначала возвращаются полные порядковые номера». Однако я не совсем уверен, что означает OP. –

+0

@ GordonLinoff - Спасибо; для уточнения, я бы предпочел избежать сканирования таблиц. Если оригинал будет работать лучше, я буду придерживаться этого. – TrueWill