2013-02-28 5 views
1

У меня простой запрос, но у меня есть несколько записей, которые нужно отфильтровать. Я использую подобное заявление с дикими картами. Есть ли лучший способ сделать это, а затем выписать каждый из них? Могу ли я создать udf, таблицу, которую он возвращает? Как? Если я могу. Спасибо :)Как SQL-запрос SQL Server 2008R2

SELECT a.SalesOrderNo , 
     a.ShipExpireDate , 
     a.CustomerNo , 
     b.ItemCode , 
     b.LineKey , 
     b.QuantityOrdered , 
     b.QuantityShipped , 
     b.ItemCodeDesc , 
     b.ExplodedKitItem 
FROM dbo.SO_SalesOrderHeader a 
LEFT JOIN dbo.SO_SalesOrderDetail b 
ON a.SalesOrderNo = b.SalesOrderNo 
WHERE b.ItemType = '1' 
    AND b.ItemCodeDesc NOT LIKE '%Cert%' 
    AND b.ItemCodeDesc NOT LIKE '%Fee%' 
    AND b.ItemCodeDesc NOT LIKE '%Tag%' 
    AND b.ItemCode NOT LIKE 'GF%' 
    AND b.ItemCode NOT LIKE 'PXDIALPREP' 
    AND b.ItemCode NOT LIKE '/C%' 
    AND a.ShipExpireDate = CONVERT(DATE, GETDATE(), 101) 
+1

Можете ли вы объяснить, почему ваши псевдонимы являются 'a' и' b'? Разве 'h' (для' header') и 'd' (для' detail') не будет на 10 000 000% больше смысла? –

+1

Также преобразование в DATE с номером стиля имеет мало смысла. Если вы хотите, чтобы все значения 'ShipExpireDate' истекали сегодня в любое время, используйте' CONVERT (DATE, ShipExpireDate) = CONVERT (DATE, GETDATE()) '. Обычно вам не очень разумно применять «CONVERT» к столбцу, но это тот случай, когда он все еще доступен (что означает, что он все равно будет использовать индекс в этом столбце, если он существует). –

+0

Да h и d имеет больше смысла. С этого момента я буду использовать это. – datacrunch

ответ

0

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

Проблема, с которой вы сталкиваетесь, является результатом сохранения дискретных значений в идентификаторе. Похоже, у вас должен быть столбец IsShippable или еще лучше таблица кодов для ItemCodeType с строками Cert, Fee, Tag и т. Д. И столбцом IsShippable. если у вас есть таблица кодов, то вы были бы в состоянии сделать

inner join ItemCodeTypes ict on ict.ItemCodeTypeId = b.ItemCodeTypeId and ict.IsShippable = 1 

Cert, плата, Tag, строки в таблице ItemCodeTypes будет иметь IsShippable = 0:

Id | Name | IsShippable 
1 Cert 0 
2 Fee  0 
3 Tag  0 
4 Product 1 
5 Book 1 

Edit: Для более прямого ответа на ваш вопрос, вы могли бы сделать вид, как это, а затем, когда вы запрашиваете из него легко фильтровать Где IsShippable = 1:

Select CASE 
    When b.ItemCodeDesc LIKE '%Cert%' Then 0 
    When b.ItemCodeDesc LIKE '%Fee%' Then 0 
--etc. 
    Else 1 
END as IsShippable 
,* 
From dbo.SO_SalesOrderDetail 
+0

Спасибо за быстрый ответ. – datacrunch

1

Вот другое дизайн, который позволяет помещать ItemCodeDesc в отдельную таблицу (это также может быть TVF). Однако я не могу комментировать производительность.

С другой стороны, имейте в виду, что, поскольку вы являетесь внешним соединением с деталями заказа клиента, эта таблица может иметь NULL-записи. В свою очередь, ваш b.ItemType = '1' всегда будет FALSE, если ItemType имеет значение NULL. Таким образом, вы можете также сделать это внутренним соединением (и вы можете найти, что ваш план запросов так или иначе делает это)

SELECT a.SalesOrderNo , 
    a.ShipExpireDate , 
    a.CustomerNo , 
    b.ItemCode , 
    b.LineKey , 
    b.QuantityOrdered , 
    b.QuantityShipped , 
    b.ItemCodeDesc , 
    b.ExplodedKitItem 
    FROM dbo.SO_SalesOrderHeader a 
    LEFT JOIN dbo.SO_SalesOrderDetail b 
    ON a.SalesOrderNo = b.SalesOrderNo 
    WHERE b.ItemType = '1' 
    AND b.ItemCode NOT LIKE 'GF%' 
    AND b.ItemCode NOT LIKE 'PXDIALPREP' 
    AND b.ItemCode NOT LIKE '/C%' 
    AND a.ShipExpireDate = CONVERT(DATE, GETDATE(), 101) 
    AND NOT EXISTS (
     SELECT 1 FROM dbo.MappingTable MT 
     WHERE b.ItemCodeDesc LIKE MT.ItemCodeDesc 
     ) 
+1

+1 для наблюдения за тем, что это ВХОДНАЯ ВСТУПЛЕНИЕ, а не ВНЕШНЯЯ ВСТУПЛЕНИЕ. –

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