【问题标题】:SQL for making suggestions when no results found未找到结果时提出建议的 SQL
【发布时间】:2009-09-16 15:24:36
【问题描述】:

非常感谢我正在尝试使用 ASP.NET 和 SQL SERVER 为卡拉 OK 音乐网站制作的搜索引擎的帮助...

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

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

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

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 搜索。

我不想进行大量搜索,因为这确实会减慢速度,并且本能地感觉应该通过使用crouping和counts来做到这一点。

任何帮助将不胜感激。

乔恩

【问题讨论】:

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


    【解决方案1】:
    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
    

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        相关资源
        最近更新 更多