SQL Server使用JOIN查询WHERE

时间:2013-05-02 20:01:45

标签: sql-server

我想做一个SELECT,这将导致数据库的伪搜索。 VS2010中使用以下SELECT与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,以便在食谱名称上进行搜索?

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

3 个答案:

答案 0 :(得分: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%'

答案 1 :(得分: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。我的其他观点仍然存在。

答案 2 :(得分: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个食谱,或者希望能够使用数百万个食谱,则必须使用全文搜索。这与调整查询完全不同。