0

我正在尝试一次搜索多个表以查找搜索词。我的查询是:

SELECT item.ItemID 
    FROM Inventory.Item item 
        JOIN Inventory.Category catR // each item can be in several categories
            ON catR.ItemID = item.ItemID 
        JOIN Category.Category cat 
            ON cat.CategoryID = catR.CategoryID 
        JOIN Inventory.Brand bran 
            ON bran.BrandID = item.BrandID
    WHERE
         item.Description LIKE '%' + @term + '%'
       OR
         item.Description LIKE '%' + @term
       OR
         item.Description LIKE @term + '%'
       OR
         item.Description = @term
       OR
         cat.CategoryName LIKE '%' + @term + '%'
             //same pattern as item.Description used to search CategoryName
             //...
       OR
         bran.BrandName LIKE '%' + @term + '%'
             //same pattern as item.Description used to search BrandName
             //...

但结果并不如预期。我在“Casement”类别中有大约 50 件商品,但是当 term == “Casement”时,只有 item.Description 中有“Casement”的商品才会被退回。

难道我做错了什么?我应该以更好的方式做到这一点吗?

4

4 回答 4

2

写就够了

item.Description LIKE '%' + @term + '%'

代替

item.Description LIKE '%' + @term + '%'
OR
   item.Description LIKE '%' + @term
OR
   item.Description LIKE @term + '%'
OR
   item.Description = @term
于 2009-11-11T20:25:48.813 回答
2

从概念上讲,我会保持简单,然后根据性能需要从那里进行更改。首先,我将创建一个视图,然后从中进行选择。

CREATE VIEW vSearchTables
AS

SELECT item.ItemID, 'Item' AS TableName, item.Descripton AS Txt
FROM Inventory.Item item

UNION ALL

SELECT catR.ItemID, 'Category' AS TableName, cat.CategoryName AS Txt
FROM Inventory.Category catR 
JOIN Category.Category cat  
ON cat.CategoryID = catR.CategoryID 

UNION ALL

SELECT item.ItemID, 'Brand' AS TableName, bran.BrandName AS Txt
FROM Inventory.Item  item
JOIN Inventory.Brand bran
ON bran.BrandID = item.BrandID 

GO



SELECT ItemID
FROM vSearchTables
WHERE Txt LIKE '%'+@term +'%'


GO

如果你有 sql2005 并且想测试这个概念,你可以运行以下命令:

CREATE VIEW vSearchTables 
AS 

select object_name(o.object_id) Object, o.type, m.definition as Txt
from sys.sql_modules m    
join sys.objects o on m.object_id = o.object_id    

GO


SELECT *
FROM vSearchTables 
WHERE Txt LIKE '%TRIGGER%' 
于 2009-11-11T22:43:51.980 回答
1

这是一个很好的 CTE 示例:

WITH items AS (
     SELECT i.itemid,
            i.description,
            cat.category_name,
            b.brandname 
       FROM INVENTORY.ITEM i 
  LEFT JOIN INVENTORY.CATEGORY c ON c.itemid = i.itemid
  LEFT JOIN CATEGORY.CATEGORY cat ON cat.CategoryID = c.categoryid
  LEFT JOIN INVENTORY.BRAND b ON b.brandid = i.brandid)
SELECT a.itemid
  FROM items a
 WHERE a.description LIKE '%' + @term + '%'
UNION ALL
SELECT b.itemid
  FROM items b
 WHERE b.categoryname LIKE '%' + @term + '%'
UNION ALL
SELECT c.itemid
  FROM items c
 WHERE c.brandname LIKE '%' + @term + '%'

SQL Server 2005+ 支持 CTE。

于 2009-11-12T03:46:22.070 回答
0

尝试这个:

Select i.ItemID    
From Inventory.Item i
  Join Inventory.Category ic
    On ic.ItemID = i.ItemID         
  Join Category.Category cc            
    On cat.CategoryID = ic.CategoryID         
  Join Inventory.Brand ib
    On ib.BrandID = i.BrandID
Where CharIndex(@Term,
      i.Description + '|' + 
     ic.Description + '|' +
     cc.Description + '|' +
     ib.Description) > 0

意识到这将导致对所有四个表进行全表扫描,因此如果这些表很大,它会很慢。但是考虑到您正在尝试做的事情,唯一的选择是在数据库上实现全文索引......

此外,如果这些表之一可能不包含与 yr 连接条件匹配的行,则应将所有连接设为外连接,并IsNull()在所有列引用上使用...

Select i.ItemID    
From Inventory.Item i
  Left Join Inventory.Category ic
    On ic.ItemID = i.ItemID         
  Left Join Category.Category cc            
    On cat.CategoryID = ic.CategoryID         
  Left Join Inventory.Brand ib
    On ib.BrandID = i.BrandID
Where CharIndex(@Term,
      i.Description + '|' + 
     IsNull(ic.Description, '') + '|' +
     IsNull(cc.Description, '') + '|' +
     IsNull(ib.Description, '')) > 0
于 2009-11-11T20:42:00.663 回答