2010-07-13 6 views
1

J'utilise sql-server 2005 et ASP.NET avec C#.Assistance avec instruction SQL

J'ai des utilisateurs table avec

userId(int), 
userGender(tinyint), 
userAge(tinyint), 
userCity(tinyint) 

(version simplifiée bien sûr)

je dois choisir toujours deux apte à userID je passe pour interroger les utilisateurs de sexe opposé, l'âge gamme de -5 à +10 ans et de la même ville.

Le fait important est qu'il doit toujours être deux, donc j'ai créé la condition si @@ rowcount < 2 resélectionnez sans les filtres d'âge et de ville.

Maintenant le problème est que j'ai parfois deux ensembles de résultats retournés parce que j'utilise d'abord @@ rowcount sur une table. Si je cours la requête.

Serait-ce un problème d'utiliser l'objet DataReader à lire à partir du second ensemble de résultats? Existe-t-il un autre moyen de vérifier combien de résultats ont été sélectionnés sans effectuer de sélection avec les résultats?

Répondre

4

Pouvez-vous le simplifier en utilisant SELECT TOP 2?

Mise à jour: J'exécuteraient les deux sélectionne tout le temps, l'union des résultats, puis sélectionnez d'eux à partir d'une commande (en utilisant SELECT TOP 2) que le syndicat peut avoir ajouté plus de deux. Il est important que cette sélection suivante sélectionne les lignes par ordre d'importance, c'est-à-dire qu'elle préfère les lignes de votre premier choix.

Vous pouvez également demander à la logique du lecteur de lire le jeu de résultats suivant s'il y en a un et de laisser le SQL seul.

+0

je peux et c'est ce que je fais. Que se passe-t-il lorsque select top 2 renvoie moins de deux enregistrements? Je dois toujours sélectionner le top 2 juste si 3 filtres ne me donnent pas deux enregistrements que je sélectionne en utilisant un filtre. – eugeneK

3

Pour éviter d'obtenir deux ensembles de résultats distincts, vous pouvez effectuer votre premier SELECT dans une variable de table, puis effectuer votre vérification @@ROWCOUNT. Si> = 2 alors sélectionnez simplement parmi les variables de la table sinon sélectionnez les résultats de la variable de table UNION ALL avec les résultats de la deuxième requête. Il est légèrement superflu d'utiliser des variables de table. Vous devez donc équilibrer si cela était moins cher que la suggestion d'Adam pour effectuer la routine UNION en regardant les statistiques d'exécution pour les deux approches

SET STATISTICS IO ON 
+0

+1 bonne place. Mon approche est plus pour réduire la complexité du code au détriment des améliorations de performances potentielles. –

+0

et @Adam je vais essayer vos deux approches créatives et voir ce qui fonctionne plus vite pour ma Table. merci. Désolé ne peut pas choisir deux réponses choisira donc le meilleur. – eugeneK

3

Would quelque chose le long des lignes suivantes être utiles ...

SELECT * 
    FROM (SELECT 1 AS prio, * 
      FROM my_table M1 JOIN my_table M2 
      WHERE M1.userID = supplied_user_id AND 
        M1.userGender <> M2.userGender AND 
        M1.userAge - 5 >= M2.userAge AND 
        M1.userAge + 15 <= M2.userAge AND 
        M1.userCity  = M2.userCity 
      LIMIT TO 2 ROWS 
      UNION 
      SELECT 2 AS prio, * 
       FROM my_table M1 JOIN my_table M2 
       WHERE M1.userID = supplied_user_id AND 
        M1.userGender <> M2.userGender 
       LIMIT TO 2 ROWS) 
    ORDER BY prio 
    LIMIT TO 2 ROWS; 

Je ne l'ai pas essayé comme je l'ai pas SQL Server et il peut y avoir des problèmes dialecte.

+0

Dans SQL Server, vous utiliseriez 'SELECT TOP 2' plutôt que l'instruction 'LIMIT' et 'UNION ALL' serait moins cher que 'UNION' mais cela fonctionnerait. –

+0

Bien. Merci, monsieur Smith. Je pense que UNION DISTINCT serait peut-être mieux. –

+0

merci. C'est plus ou moins ce que Adam a dit juste avec un exemple. – eugeneK