SQL для предложения, когда ничего не найдено - PullRequest
2 голосов
/ 16 сентября 2009

Буду очень признателен за помощь в поиске, которую я пытаюсь создать для музыкального сайта караоке с использованием ASP.NET и SQL SERVER ...

У меня есть таблица с именем Диски , которая имеет следующие поля:

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 условия для нас. А) он хочет использовать совпадение «старт с» для каждого элемента, следовательно, подстановочный знак в конце каждого НРАВИТСЯ, и Б) он не хочет использовать поиск MSSQL Full TEXT.

Я не хочу делать много поисков, так как это действительно замедлит ход событий, и инстинктивно кажется, что должен быть какой-то способ сделать это с помощью группирования и подсчета.

Любая помощь будет принята с благодарностью.

Jon

Ответы [ 2 ]

2 голосов
/ 16 сентября 2009
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 голосов
/ 16 сентября 2009

В основном у вас есть 2 варианта: (1) каждый раз запускать частичные запросы или (2) поддерживать таблицу агрегированных счетчиков, которая периодически обновляется.

Исходя из того, что большинство поисков в среднем будут возвращать хиты, я выбрал бы вариант (1) и обеспечил бы наличие хороших индексов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...