2

我想做一个 SELECT ,这将导致数据库的伪搜索。以下 SELECT 在 VS2010 中与 SQL Server 一起使用:

SELECT *
FROM
(
   SELECT RecipeID, COUNT(*) AS Count, AVG(Rating) AS RatingAVG
   FROM AsianRating
   GROUP BY RecipeID
) AS AsianRatingAVG
INNER JOIN
(
   SELECT AsianRecipe.RecipeID, AsianRecipe.Category
      , AsianRecipe.NAME, AsianRecipe.Description
   FROM AsianRecipe
) AS AsianRecipe ON (AsianRatingAVG.RecipeID = AsianRecipe.RecipeID)

如果没有使用 JOIN 并且只使用了 AsianRecipe 表,我可以搜索食谱名称。这三个表使用 RecipeID (int) 作为键。这三个表中的名称并不常见。如果没有 JOIN,使用 SEARCH 文本框,如果与 WHERE 一起使用,以下将给出伪搜索:

<SelectParameters>
   <asp:FormParameter FormField="Name" Name="Name" Type="Int32" />
</SelectParameters>

有没有办法使用上面的查询编写 WHERE,以便在食谱名称上进行搜索?

如果只输入部分名称,有没有办法进行搜索?任何帮助将不胜感激!

4

3 回答 3

2

如果您没有制作两个派生表,而只有一个会做(对于预聚合),那会容易得多。

SELECT rep.RecipeID, rep.Category, rep.NAME, rep.[Description],
       rat.[Count], rat.RatingAVG
FROM
( -- pre-aggregated
   SELECT RecipeID, COUNT(*) AS Count, AVG(Rating) AS RatingAVG
   FROM AsianRating
   GROUP BY RecipeID
) AS rat
JOIN AsianRecipe rep ON rat.RecipeID = rep.RecipeID;
-- WHERE rep.name LIKE '%partial%'
于 2013-05-02T20:17:05.883 回答
2

我不确定这是否比加入派生表更快,但我更喜欢它的外观:

SELECT re.RecipeID
    , re.Category
    , re.NAME
    , re.Description
    , count(ra.RecipeID) AS [Count]
    , avg(ra.Rating) AS RatingAVG
FROM AsianRecipe re
    LEFT JOIN AsianRating ra ON re.RecipeID = ra.RecipeID
WHERE re.NAME LIKE '%' + @Name + '%' -- Your partial match search
GROUP BY re.RecipeID
    , re.Category
    , re.NAME
    , re.Description

您可以删除'%'完全匹配的。

请注意,这也会得到没有评级的食谱。如果不正确,请更改LEFT JOIN为。JOIN

此外,如果有人在您的搜索框中输入了多个词,您可能需要拆分多个搜索词。一种快速而肮脏的方法是,replace(@Name, ' ', '%')但这只会以相同的顺序找到搜索词。

更新

使用派生表(或 CTE)创建聚合是我的盒子上最快的方法。接下来是相关子查询,最后是我的原始查询。非常非正式的测试...YMMV。

因此,我赞成@RichardTheKiwi。我的其他观点仍然成立。

于 2013-05-02T20:17:55.723 回答
0

即使您编写了 Int32,我仍假定您的意思是该表单输入字段是一个字符串。

select *
from 
(
[Your 'Original' Query]
) X
WHERE Name like '%'+@Name+'%'

您在原始查询中使用了两次“RecipeID”,因此您需要对其进行调整,否则您没问题。

或者

SELECT *
FROM
(
   SELECT RecipeID, COUNT(*) AS Count, AVG(Rating) AS RatingAVG
   FROM AsianRating
   GROUP BY RecipeID
) AS AsianRatingAVG
INNER JOIN
(
   SELECT AsianRecipe.RecipeID, AsianRecipe.Category
      , AsianRecipe.NAME, AsianRecipe.Description
   FROM AsianRecipe
WHERE AsianRecipe.NAME like '%'+@Name+'%'  -- ADDED A NEW LINE HERE!!!
) AS AsianRecipe ON (AsianRatingAVG.RecipeID = AsianRecipe.RecipeID)

!!!笔记!!!这不会很好地扩展!

但如果你的数据库只有一千个左右的食谱,你会没事的。

如果您有 1000 种食谱,或者希望能够处理数百万种食谱,您将不得不使用全文搜索。这与调整查询完全不同。

于 2013-05-02T20:12:21.857 回答