用于在未找到结果时提供建议的SQL

时间:2009-09-16 15:24:37

标签: asp.net sql sql-server sql-server-2005 search

我真的很感激使用ASP.NET和SQL SERVER为一个卡拉OK音乐网站制作搜索角色的一些帮助......

我有一张名为 Discs 的表格,其中包含以下字段:

  

ID,DiscCode,DiscTitle,DiscType,   主题,制造商

还有一个名为曲目的表格,其中包含以下字段

  

ID,DiscID,艺术家,标题

好的,假设用户搜索以下内容......

Artist: Michael Jackson
Title: Thriller
Theme: Pop
Manufacturer: Sunfly
DiscType: cdg

我会使用像这样的SQL语句....

SELECT D.ID, T.Artist, T.Title, D.Manufacturer, D.DiscTitle 
FROM Discs D
INNER JOIN Tracks T
ON T.DiscID = D.ID 
WHERE T.Artist LIKE 'Michael JAckson%' 
AND T.Title LIKE 'Thriller%' 
AND D.Theme = 'Pop' 
AND D.Manufacturer = 'Sunfly' 
AND DiscType = 'DVD';

这样可以正常工作,但如果没有找到结果,我真的希望能够告诉用户如果任何过滤器被计数删除,他们会获得多少结果,就像ebay那样......

对不起,没有找到结果,但我们确实找到了类似的结果。

不同的艺术家(13)

不同制造商(4)

不同主题(2)

客户对我们有2条规定。 A)他想在每个项目上使用“startswith”匹配,因此每个LIKE结束时使用通配符,B)他不想使用MSSQL Full TEXT搜索。

我不想进行大量的搜索,因为这会让事情变得缓慢,本能地感觉应该通过使用集合和计数来做到这一点。

真的很感激任何帮助。

乔恩

2 个答案:

答案 0 :(得分:2)

您基本上有两个选择:(1)每次运行部分查询,或(2)维护定期更新的聚合计数表。

假设大多数搜索平均会返回命中,我会选择(1)并确保你有好的索引。

答案 1 :(得分:2)

SELECT  SUM(CASE WHEN cnt = 3 THEN 1 ELSE 0 END) AS exact_matches,
        SUM(CASE WHEN artist LIKE 'Michael Jackson%' THEN 0 ELSE 1 END) AS diff_artist,
        SUM(CASE WHEN theme = 'Pop' THEN 0 ELSE 1 END) AS diff_theme,
        SUM(CASE WHEN manufacturer = 'Sunfly' THEN 0 ELSE 1 END) AS diff_manufacturer
FROM    (
        SELECT  t.id, COUNT(*)  AS cnt
        FROM    (
                SELECT  t.id
                FROM    tracks t
                JOIN    discs d
                ON      t.discID = d.id
                WHERE   t.artist LIKE 'Michael Jackson%'
                UNION ALL
                SELECT  t.id
                FROM    tracks t
                JOIN    discs d
                ON      t.discID = d.id
                WHERE   d.theme  = 'Pop'
                UNION ALL
                SELECT  t.id
                FROM    tracks t
                JOIN    discs d
                ON      t.discID = d.id
                WHERE   d.manufacturer = 'Sunfly'
                ) q
        GROUP BY
                t.id
        HAVING  COUNT(*) >= 2
        ) q2
JOIN    table t
ON      t.id = q2.id
JOIN    discs d
ON      d.id = t.discID

这是索引友好的,因为它运行三个单独的查询,每个查询使用自己的计划。