2009-09-16 6 views
2

apprécierions vraiment un peu d'aide avec une recherche que je angine essaie de faire pour un site de musique karaoké en utilisant ASP.NET et SQL SERVER ...SQL pour faire des suggestions quand aucun résultat trouvé

J'ai une table appelée disques qui a les champs suivants:

ID, DiscCode, DiscTitle, DiscType, Thème , Fabricant

Il y a aussi une table appelée Pistes avec les champs suivants

ID, discid, Artiste, Titre

OK, alors imaginez un utilisateur effectue une recherche de ce qui suit ...

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

Je voudrais utiliser une instruction SQL comme ceci ....

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'; 

Je travaille bien, mais si aucun résultat n'est trouvé, je veux vraiment pouvoir dire à l'utilisateur combien de résultats ils obtiendraient si l'un des filtres était enlevé avec un compte, comme ebay ...

Désolé, Aucun résultat n'a été trouvé mais nous avons trouvé des résultats similaires.

différents artistes (13)

différents fabricants (4)

thèmes différents (2)

Le client dispose de 2 dispositions pour nous. A) il veut utiliser une correspondance "startswith" sur chaque élément, d'où le caractère générique à la fin de chaque LIKE, et B) il ne veut pas utiliser la recherche MSSQL Full TEXT.

Je ne veux pas avoir à faire beaucoup de recherches car cela va vraiment ralentir les choses et instinctivement, il semble qu'il devrait y avoir une certaine façon de le faire en utilisant le croupage et compte.

Toute aide serait vraiment appréciée.

Jon

Répondre

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 

Ceci est facile à utiliser, car il exécute trois requêtes distinctes, chacune utilisant un plan qui lui est propre.

2

Vous avez essentiellement 2 choix: (1) exécuter les requêtes partielles à chaque fois, ou (2) maintenir une table de comptage global qui est mis à jour périodiquement.

En supposant que la plupart des recherches renverront des résultats en moyenne, j'opterais pour l'option (1) et je m'assurerais que vous avez de bons index en place.

Questions connexes