Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/03/2011, 10h22   #1
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Par défaut SQL-SERVER 2005 - Deux conditions opposées dans une seule et même requête

Bonjour,

j'ai un 1er code qui me permet de prendre 2 lignes aléatoires dans une table avec une condition de type
Code :
1
2
3
4
SELECT TOP 2
FROM MA_TABLE
WHERE COLONNE_1 = 'A'
ORDER BY NEWID()
J'ai ensuite un 2ème code qui me fait la meme chose, mais avec la condition
Code :
1
2
3
4
SELECT TOP 2
FROM MA_TABLE
WHERE COLONNE_1 = 'B'
ORDER BY NEWID()
Est-il possible de combiner les deux requêtes en une seule (sans complexifier le code ou alourdir les performances) pour qu'il m'affiche 4 lignes, avec :
- les 2 premières satisfaisant ma première condition, et
- les 2 dernières, la deuxième condition.

?

(ces résultats seront ensuites exportés vers un fichier Excel)

Merci d'avance.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 10h45   #2
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
   SELECT * 
   FROM(
      SELECT TOP 2 *
      FROM MA_TABLE
      WHERE COLONNE_1 = 'A'
      ORDER BY NEWID()
           ) AS T
UNION
   SELECT * 
   FROM(
      SELECT TOP 2
      FROM MA_TABLE
      WHERE COLONNE_1 = 'B'
      ORDER BY NEWID()
           ) AS T2
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 10h55   #3
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Je reviens vers vous après avoir tester.
Merci pour l'idée.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 11h30   #4
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Merci, ca fonctionne nickel.

Par contre, j'aimerai aller un peu plus loin.

Est-il possible que la requête fasse un check sur la deuxieme table (résultats de la deuxième table), et si celle-ci est vide, qu'il me prenne alors 4 lignes aléatoires de ma première table, au lieu de 2.

Car mon tableau final DOIT contenir 4 lignes !

Donc:
soit 2 A et 2 B (dans le meilleur des cas)
soit 3 A et 1 B (sinon)
soit 4 A et 0 B (au pire).

J'espère avoir été assez clair ;-)
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 11h42   #5
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Vous partez donc du principe que seul la requête 2 peux ne pas renvoyer deux enregistrements?
La première requête renverra toujours 2,3,4 enregistrements?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 11h44   #6
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT TOP 4 * 
FROM(
SELECT TOP 2 *,1 AS Ordre
FROM MA_TABLE
WHERE COLONNE_1 = 'B'
ORDER BY NEWID()
) AS T
UNION
SELECT * 
FROM(
SELECT TOP 4 *,2 AS Ordre
FROM MA_TABLE
WHERE COLONNE_1 = 'B'
ORDER BY NEWID()
) AS T2
ORDER BY Ordre
Principe: votre résultat est trié avec les résultats du B en premier... ainsi la requete ne prendra que maximum deux 'B' et fera le complément avec A pour obtenir 4...
NB: Je n'accepte pas les bisous :-)
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 11h46   #7
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Je peux mettre mettre les conditions susceptibles de donner le plus de résultats en amont, effectivement, mais rien ne garantit que la première condition comporte 4 résultats. Je dois avoir au max 4 lignes, et le plus de lignes possibles.

Je réponds donc OUI à 80%.

Merci pour votre aide.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 11h58   #8
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Citation:
Envoyé par iberserk Voir le message
SELECT TOP 4 *
FROM(
SELECT TOP 2 *,1 as Ordre
FROM MA_TABLE
WHERE COLONNE_1 = 'B'
ORDER BY NEWID()
) as T
UNION
SELECT *
FROM(
SELECT TOP 4 *,2 as Ordre
FROM MA_TABLE
WHERE COLONNE_1 = 'B'
ORDER BY NEWID()
) AS T2
ORDER BY Ordre
Astucieux, mais etrangement, lorsqu'il existe 2 résulats dans la premiere requête et 4 dans l'autre, mon résultat me donne 6 lignes !! ?
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h31   #9
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par apnw7931 Voir le message
Je réponds donc OUI à 80%.
Je ne suis pas sûr de bien saisir...

Vous voulez 4 lignes, si l'une ou l'autre des conditions n'est pas vérifiée pour 2 lignes au moins, alors "completer" avec les résultats de l'autre condition ?

Est-ce que ceci vous donne ce que vous voulez :
Code SQL :
1
2
3
4
5
6
7
8
9
 
SELECT TOP(4) * -- <- spécifiez le nom des colonnes !
FROM(
    SELECT ROW_NUMBER() OVER (PARTITION BY COLONNE_1 ORDER BY NEWID()) AS RN, * --<-- ici aussi ;)
    FROM MA_TABLE
    WHERE COLONNE_1 = 'A'
    OR COLONNE_1 = 'B'
) T 
ORDER BY RN
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h35   #10
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Astucieux, mais etrangement, lorsqu'il existe 2 résulats dans la premiere requête et 4 dans l'autre, mon résultat me donne 6 lignes !! ?
Avez vous bien pris l’intégralité de la requête y compris le top 4 du haut?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h36   #11
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par apnw7931 Voir le message
Astucieux, mais etrangement, lorsqu'il existe 2 résulats dans la premiere requête et 4 dans l'autre, mon résultat me donne 6 lignes !! ?
C'est normal !
Vous faites le TOP 4 sur le résultat de la première requête (UN TOP 2), puis un UNION avec un autre top 4
La première partie vous renvoie donc 2 lignes maximum, auxquelles vous ajoutez 4 lignes... cela fait bien 6 lignes

Pour cette requête, vous devez donc faire le TOP 4 sur le résultat de l'union
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h38   #12
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
SELECT TOP(4) * -- <- spécifiez le nom des colonnes !
FROM(
SELECT ROW_NUMBER() OVER (PARTITION BY COLONNE_1 ORDER BY NEWID()) AS RN, * --<-- ici aussi
FROM MA_TABLE
WHERE COLONNE_1 = 'A'
OR COLONNE_1 = 'B'
) T
ORDER BY RN
Je ne suis pas certains que cela fonctionne car si j'ai bien compris (et seulement dans ce cas là...) apnw7931 veux au plus deux valeur de 'B' et compléter par 'A' pour avoir 4 enregistrements?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h38   #13
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Après un premier test, ca semble correspondre à mon besoin.
Je vais essayer de faire ca avec 3 conditions maintenant..

Je reviendrai plus tard avec mes remarques, si besoin.

Merci encore.
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h42   #14
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Quelle solution?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h45   #15
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Citation:
Envoyé par iberserk Voir le message
Je ne suis pas certains que cela fonctionne car si j'ai bien compris (et seulement dans ce cas là...) apnw7931 veux au plus deux valeur de 'B' et compléter par 'A' pour avoir 4 enregistrements?
Je veux, dans mon exemple, 4 lignes en tout.
Idéalement, 2 lignes qui satisfait la première condition et 2 lignes satisfaisant la deuxième condition.

Mais il se peut que l'une des deux conditions ne soit pas respectée (la premiere ou la deuxième). Donc pour être sur d'avoir mes 4 lignes, je veux compenser l'un par l'autre.

Ainsi, si possible :
2 A et 2 B
3 A et 1 B (si seulement 1 B dispo)
4 A et 0 B (si aucun B dispo)
1 A et 3 B (si seulement 1 A dispo)
0 A et 4 B (si aucun A dispo)
1 A et 1 B (si seulement 1 A et 1 B dispo)
2 A et 0 B (si seulement 2 1 dispo et aucun B dispo)

Voyez vous plus clair ??
Désolé si je me suis mal exprimé..


La solution de aieeeeeeee semble correspondre (jusqu'a présent)
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h47   #16
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Très bien je pensais que nbr da A<2 était impossible...

Je ne vois pas en quoi la proposition de Aieeeeeeeeeeee( j'ai oublié un e non? ) vous permet de vous assurer d'avoir 2 A et 2 B?

Aieeeeee une explication?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h51   #17
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Mon problème se complique avec ceci.
puisque mes deux requêtes sont en fait :

CONDITION 1 : COLONNE_1 IN ('A', 'C', 'E')
CONDITION 2 : COLONNE_1 IN ('B', 'D', 'F')

Donc ici, j'aimerai 2 lignes satisfaisant la condition 1 ET 2 lignes satisfaisant la condition 2
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h53   #18
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Cherchez un peu par vous même...
Nous vous avons montré les propositions pour une condition donnée... adaptez la conditions en fonction de vos besoin...
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 12h55   #19
Futur Membre du Club
 
Inscription : décembre 2010
Messages : 125
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 125
Points : 19
Points : 19
Citation:
Envoyé par iberserk Voir le message
Cherchez un peu par vous même...
Nous vous avons montré les propositions pour une condition donnée... adaptez la conditions en fonction de vos besoin...

Oui, d'ailleurs, je n'hésite jamais a chipoter avant de répondre ici.
Mais avec le code de aieeeuuuuu, que j'ai modifié avec mes conditions, j'ai ceci :

Code :
1
2
3
4
5
6
7
SELECT TOP(4) * -- <- spécifiez le nom des colonnes !
FROM(
SELECT ROW_NUMBER() OVER (PARTITION BY COLONNE_1 ORDER BY NEWID()) AS RN, * --<-- ici aussi 
FROM MA_TABLE
WHERE COLONNE_1 IN ('A', 'C', 'E') OR COLONNE_1 IN ('B', 'D', 'F')
) T 
ORDER BY RN
Et du coup, cela ne fonctionne plus correctement du fait que je n'ai plus DEUX valeurs possibles pour ma condition, mais plus. En réalité, comme vous pouvez le voir, ce sont deux groupes de conditions différent.

Je devrais pouvoir avoir un résultat comme suit :
A <-- 1ERE CONDITION
A <-- 1ERE CONDITION
D <-- 2EME CONDITION
F <-- 2EME CONDITION

Autre exemple pratique (hypothèse, pas de B, D et F)
A <-- 1ERE CONDITION
A <-- 1ERE CONDITION
A <-- 1ERE CONDITION
C <-- 1ERE CONDITION

et non pas systématiquement moitié/moitié (comme le fait la requête d'aieeeuuuuu)
A <-- 1ERE CONDITION
A <-- 1ERE CONDITION
C <-- 1ERE CONDITION
C <-- 1ERE CONDITION


Merci de vous pencher sur mon problème..
apnw7931 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 13h19   #20
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par iberserk Voir le message
Je ne vois pas en quoi la proposition de Aieeeeeeeeeeee( j'ai oublié un e non? ) vous permet de vous assurer d'avoir 2 A et 2 B?

Aieeeeee une explication?
Elle ne permet pas d’être sûr d'avoir 2 lignes de chaque...
elle permet d'avoir un nombre équilibré (par rapport à la valeur de la colonne_1) tant que faire ce peut :
Code SQL :
1
2
 
ROW_NUMBER() OVER (PARTITION BY COLONNE_1 ORDER BY ROWID) AS RN
Je classe sur ROWID distinctement pour chaque valeur de COLONNE_1 :
La "première" ligne pour COLONNE_1 = 'A' aura RN = 1
La "deuxième" ligne pour COLONNE_1 = 'A' aura RN = 2
La "première" ligne pour COLONNE_1 = 'B' aura RN = 1 également

A la fin, en classant sur RN, on aura en "premier" les "premières" ligne pour chaque valeur de COLONNE_1
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h56.


 
 
 
 
Partenaires

Hébergement Web