[resolu] top 5 sur inner join

top 5 sur inner join [resolu] - SQL/NoSQL - Programmation

Marsh Posté le 20-01-2010 à 14:14:25    

bonjour,
 
je fais une requete afin de ressortir des préférences d'abonnés à un site.
ces abonnés peuvent avoir autant de préférences qu'ils le souhaitent.
ce que je voudrais, c'est ne ressortir que 5 préférences parmi ce qu'ils ont choisi.
en gros faire un top 5 sur un des inner join...
sur le dernier inner join :  

Citation :

inner join ligne l on al.ligno=l.ligno


et là je cale...
 

Citation :

select
u.usr_nom,
u.usr_prenom,
u.usr_telephone,
u.usr_email,
u.usr_adresse,
u.usr_code_postal,
u.usr_ville,
u.usr_date_naissance,
u.usr_sexe,
a.abn_sms,
a.abn_mail,
a.abn_newsletter,
l.lignomcommercial
from utilisateur u  
inner join abonnement a on u.usr_id=a.usr_id  
inner join abonnement_ligne al on a.abn_id=al.abn_id  
inner join ligne l on al.ligno=l.ligno
where usr_login like ('%@%')and (abn_mail =1 or abn_newsletter =1)  
order by usr_email


 
Si quelqu'un peut m'aider
 
merci d'avance


Message édité par MonGhost le 28-01-2010 à 17:18:07
Reply

Marsh Posté le 20-01-2010 à 14:14:25   

Reply

Marsh Posté le 21-01-2010 à 09:33:06    

Je ne suis pas sur de mon coup :  
 
Mais j'aurais viré ca "inner join ligne l on al.ligno=l.ligno" et dans le "WHERE" j aurais ajoté une condition du style "al.ligno IN (SOUS REQUETE OU JE RETOURNE 5 ABOS)"

Reply

Marsh Posté le 23-01-2010 à 12:38:49    

Merci Oreste, je vais regarder

Reply

Marsh Posté le 25-01-2010 à 16:57:36    

le problème est que l'implémentation de LIMIT n'existe pas sous SQL SERVER à la différence de MySQL. c'est donc la bouteille à l'encre...

Reply

Marsh Posté le 25-01-2010 à 17:10:06    

limit Mysql = top en SQL server (à partir de la version 2005).
 
donc quelquechose comme select top 5 * from matable
 
pour les version antérieures à 2005, il faut bricoler un peu (on simule un rownum):
 
select t.*, identity(int, 1, 1) as seq
into #t
from test as t
order by t.column1
 
select *
from #t
where seq between 1 and 5
 


---------------
Don't fuck me, I'm anonymous.
Reply

Marsh Posté le 25-01-2010 à 18:56:49    

je vais essayer ça demain, merci E-Nyar

Reply

Marsh Posté le 27-01-2010 à 14:21:43    

(euh, le top, ça existe depuis toujours sous SQL Server... la première version, qui est la 6.5, le supportait en tout cas !)
 
(avant la 6.5 c'était pas sql server, mais un autre produit qu'a raché microsoft, histoire de couper court à tout commentaire sur la numérotation étrange de microsoft ;))
 
 
par contre, TOP, que ce soit en 2005, après ou avant, ne fait que 1 à X. LIMIT, fait de X à Y, donc la bidouille du identity reste de rigueur encore aujourd'hui (à noter que... avant 2005, je suis pas sûr que c'était supporté, mais de toute façon il y a d'autres solutions plus performantes pour arriver au même résultat)

Reply

Marsh Posté le 27-01-2010 à 17:45:55    

je n'arrive pas à m'en sortir.
en fait j'ai une table abonnement avec une clé primaire abn_id liée à une table abonnement_ligne sur abn_id et un champ Ligno de cette deuxième table qui peut avoir de 1 a n occurences.  
 
or quand j'essaie la methode de E-Nyar, j'incrémente un sequence mais je n'arrive pas à ce que je veux :
 
je voudrais avoir une séquence de 1 à n sur le champ ligno de la table abonnement_ligne mais dont l'incrément recommence à chaque nouveau abn_id.
 
après je mettrais un where de 1 a 5....
et là... :pfff:


Message édité par MonGhost le 27-01-2010 à 17:47:45
Reply

Marsh Posté le 27-01-2010 à 17:53:48    

Essaie avec les fonctions de partitionnement...
 

Code :
  1. SELECT client, preference, ROW_NUMBER() OVER(ORDER BY client DESC) nb
  2. FROM matable


 
Sans garantie cependant.

Reply

Marsh Posté le 27-01-2010 à 20:22:50    

Si les fonctions analytiques ne passent pas essaie :
 
Select l.abn_id, l.ligno, count(*)
from abonnement_ligne l
left outer join abonnement_ligne as r
    on l.abn_id = r.abn_id
    and l.ligno >= r.ligno
group by l.abn_id, l.ligno
having count(*) <= 5


Message édité par E-Nyar le 27-01-2010 à 20:24:32

---------------
Don't fuck me, I'm anonymous.
Reply

Marsh Posté le 27-01-2010 à 20:22:50   

Reply

Marsh Posté le 28-01-2010 à 16:42:51    

Merci à tous et en particulier à toi E-nyar, j'ai pris ta requete et je l'ai un tout petit peu aménagée pour répondre à mon besoin.
en effet, ayant des requetes imbriquées, je ne pouvais pas avoir plus d'un champ selectionné dans la sous-requete :
j'ai donc fait une table temporaire... ce n'est pas très propre mais ça marche
 

Citation :

Select l.abn_id, l.ligno, count(*) as seq  
into #t2
from abonnement_ligne l  
left outer join abonnement_ligne as r  
    on l.abn_id = r.abn_id  
    and l.ligno >= r.ligno  
group by l.abn_id, l.ligno  
having count(*) <= 5
order by l.abn_id;
 
select distinct  
u.usr_nom,
u.usr_prenom,
u.usr_telephone,
u.usr_email,
u.usr_adresse,
u.usr_code_postal,
u.usr_ville,
u.usr_date_naissance,
u.usr_sexe,
a.abn_sms,
a.abn_mail,
a.abn_newsletter,
l.lignomcommercial
from utilisateur u  
inner join abonnement a on u.usr_id=a.usr_id  
inner join abonnement_ligne al on a.abn_id=al.abn_id  
inner join #t2 on al.abn_id=#t2.abn_id
inner join ligne l on l.ligno = #t2.ligno
where usr_login like ('%@%')and (abn_mail =1 or abn_newsletter =1 )
and al.abn_id in (Select abn_id
from #t2) and al.ligno in (select ligno from #t2)
order by usr_email;


 
merci encore.


Message édité par MonGhost le 28-01-2010 à 16:43:48
Reply

Marsh Posté le 28-01-2010 à 17:10:14    

de rien :jap:


---------------
Don't fuck me, I'm anonymous.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed