Sélection différente suivant contenu d'un champ

Résolu
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 - 3 déc. 2011 à 23:00
pradiergael Messages postés 13 Date d'inscription jeudi 7 mai 2009 Statut Membre Dernière intervention 11 décembre 2011 - 8 déc. 2011 à 22:53
Salut à tous.
(Le titre est un peu bidon, je ne sais pas trop résumer mon problème)

J'ai une requete particulière à faire, et je manque d'inspiration.

Le contexte :
J'ai une table produit avec diverses informations et dont le code (clé primaire) est codé de la sorte : référence ou référence-indice (ex: ABC, CDF, GHF-A, GHF-B, MLK, OIU-D,OIU-H, ....). L'indice, quand il existe est généralement 1 lettre, parfois 2.

La requête :
Je dois récupérer une liste pour charger le datasource d'une grille, liste comportant toutes les références sans indice ainsi que, pour les références avec indice, seulement la référence avec l'indice le plus élevé.


[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i

18 réponses

pradiergael Messages postés 13 Date d'inscription jeudi 7 mai 2009 Statut Membre Dernière intervention 11 décembre 2011
4 déc. 2011 à 22:23
solution commerciale ... j'espère que c'est pas cher !

concernant ma proposition précédente, il manque une vérif d'égalité sur code_seul et substring(T.code,1,charindex(T.code,'-'))

concernant la requête, s'il s'agit de SQL 2005 ou 2008, il devrait être interessant d'utiliser les CTE :

with TMP as
(
  select max(code) as code,code_seul 
  from ( select code, substring(code,1,charindex(code,'-')-1) as code_seul 
         from Table where code like '%-%') t1
  group by code_seul
)
select xxx,yyy from Table where code not like '%-%'
union
select T.xxx,yyy from Table T inner join TMP on T.code = TMP.code


ca parait plus simple comme ceci, et plus rapide
3
pradiergael Messages postés 13 Date d'inscription jeudi 7 mai 2009 Statut Membre Dernière intervention 11 décembre 2011
5 déc. 2011 à 22:03
Bonjour,

se trainer les boulettes vieilles de 15 ans pour assurer la compatibilité, je connais !!

sonon, odbc n'est pas en cause, c'est la version (SQL 2000) : elle ne sait pas utiliser les CTE (with ...)

essayons ceci :

select xxx,yyy from Table where code not like '%-%'
union
select T.xxx,T.yyy from Table T 
inner join 
( select max(code) as code,code_seul 
  from ( select code, substring(code,1,charindex(code,'-')-1) as code_seul 
         from Table where code like '%-%') t1
  group by code_seul
) as TMP on T.code = TMP.code


En espèrant que ce soit plus probant.
3
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
6 déc. 2011 à 11:23
Bon, par le driver ODBC, ça ne marche pas. CharIndex n'est pas reconnue, apparemment les jointures directement sur du Select, c'est pas reconnue non plus, ...


Par contre, j'ai tenté de passer par SQL2000 et le serveur lié avec ceci :
if exists(select name from tempdb..sysobjects where name like '#FTARTICLE%') 
begin drop table #FTARTICLE END;
SELECT ar_ref,ar_design,commentaire_tarif,CASE ar_nomencl WHEN 0 THEN ar_punet WHEN 1 THEN ar_coutstd end as prixachat,ar_coef,famille,estim_tps_fab,ar_prixven INTO #FTARTICLE
FROM OPENQUERY(SAGE100,'SELECT a.*, c1.cl_code + ''-'' + c2.cl_intitule AS famille
FROM f_article a INNER JOIN f_catalogue c1 ON a.cl_no1 c1.cl_no INNER JOIN f_catalogue c2 ON a.cl_no2 c2.cl_no
WHERE (c1.cl_code ''AC'' OR c1.cl_code ''FB'') AND a.ar_sommeil=0');

select * from #FTARTICLE where ar_ref not like '%-%'
union
select T.* from #FTARTICLE T 
inner join 
( 
  select max(ar_ref) as ar_ref,code_seul 
  from ( 
         select ar_ref, substring(ar_ref,1,charindex(ar_ref,'-')-1) as code_seul 
         from #FTARTICLE where ar_ref like '%-%'
       ) t1
  group by code_seul
) 
as t2 on T.ar_ref = t2.ar_ref

mais charindex me renvoie systématiquement 0


[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
3
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
6 déc. 2011 à 12:02
Salut,

d'après MSDN les paramètres de la fonction charindex sont dans l'autre sens :
charindex('-', ar_ref)
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cgandco Messages postés 219 Date d'inscription mercredi 26 octobre 2011 Statut Membre Dernière intervention 22 juin 2017 9
4 déc. 2011 à 13:10
Bonjour,

Deux petites questions :

1) Quel est le type de ton champ ?

2) La reference comporte toujours 3 caractères ?

Bonne journée




Faites simple, aussi simple que possible, mais pas simpliste.
A. Einstein.
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
4 déc. 2011 à 13:42
Le champ est de type chaine de caractère, équivalent varchar sous sqlserver, longueur maxi 19 caractères.

Non les références sont de longueur variable (3 caractères c'est le hasard des exemples donnés). Pour celles qui ont un indice, celui-ci est toujours séparé de la réfécence par le caractère - et de longueur variable (normalement 1 caractère, mais j'ai quelques références mal codifiées avec un indice sur 2 caractères, mais il n'est pas impossible que d'autres mauvaises codifications à l'avenir, entrainent des indices sur plus de caractères)

[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
pradiergael Messages postés 13 Date d'inscription jeudi 7 mai 2009 Statut Membre Dernière intervention 11 décembre 2011
4 déc. 2011 à 19:43
Bonjour,

Je m'interroge sur le bienfondé de conserver deux informations dans un seul champ. Ceci ne respecte pas la première forme normale !!
Il serait peut-être souhiatable de créer une colonne indice, colonne nullable.

Cela étant dit, je vous propose de faire ceci:

select ... from Table where code not like '%-%'
union
select ... from Table T where exists 
( select 1 
  where T.code = select code 
                 from 
                 ( select max(code) as code ,code_seul 
                   from 
                   (
                     select code,
                       substring(code,1,charindex(code,'-')-1) as code_seul 
                    from Table where code like '%-%'
                   ) tmp
                   group by code_seul
                 )
)


en terme de performances, ajouter une colonne index vous permettrait qd même d'optimiser largement ce genre de requete



en terme
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
4 déc. 2011 à 20:51
Je ne maitrise pas la structure de la table (y compris les index) puisque elle appartient à un logiciel commercial. Mais la colonne en question étant la clé primaire, j'ose espérer que l'index y est bien créé dessus.

Quant à la notion de référence/indice, c'est une notion de codification propre à l'organisation de l'entreprise. Pour le logiciel, cette colonne est une référence article unique, indépendamment de sa codification.

La performance est ce qui va poser le plus de problème. Je suis obligé de passer par un driver ODBC propriétaire pour attaquer la base, driver qui est d'une lenteur extrême. J’essaierais, normalement demain, cette requete, mais vu sa constitution, je m'attend déjà, pour environ 9 à 10 000 lignes retournées à une exécution de plusieurs minutes.

Une des solutions serait de passer sur une base SQL, mais, là, le problème est le coût prohibitif (pour une entreprise extrêmement radine) des licences à changer.


[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
4 déc. 2011 à 22:47
Solution commerciale quand même pas donnée (SAGE100)
Ce n'est pas vraiment le logiciel qui est en cause, mais l'utilisation qui en est faite. Et encore, tout ça est très récent (2 mois), les données viennent, elles, d'une appli interne qui a plus de 15 ans et dont le but est d'en abandonner une partie seulement, pour la remplacer par SAGE100.

D’où la contrainte, on supprime une partie, donc à adapter au nouveau logiciel, mais on ne peut rien casser car il faut garder la compatibilité avec ce qui reste et donc tous les historiques, etc ...
Donc pour résumer, on change le logiciel mais on garde toutes les merdes faites depuis 15ans, et en plus, on est obliger de faire des contorsions pour que tout ce la marche à peu près.

Pour SQL, c'est du 2000, sur un WS2003-32 avec 4Go de ram, qui est aussi contrôleur AD, serveur Exchange, contrôleur AV (sophos), serveur de fichier, contrôleur de backup, serveur web pour 3 sites dont l'intranet, serveur FTP, et j'en oublie surement.
Le pauvre serveur, il est sur les genoux. Mais à part dire que ça rame, ça n’inquiète pas grand monde


[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
5 déc. 2011 à 17:11
Bon les requetes ne marchent pas.

Le "Select 1 Where" est vu comme une erreur de syntaxe, le "With TMP .." n'est pas reconnu non plus.

Ce driver ODBC est vraiment une merde.


[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
5 déc. 2011 à 22:22
Heuu, pour le coup, j'ai fait les tests en direct sur l'odbc, sans passer par SQL2000, donc ça ne vient pas de SQL2000.
Mais le driver odbc de Sage n'est pas mieux, et même pire. Il n'accepte pas tout, ne connais pas par exemple la requete paramétrée, ...

Si tu ne le connais je te conseille vivement ..... de n'avoir jamais à le connaitre.

J’essairai ça demain, mais je pense déjà que le "inner join ( select" risque de pas passer.

Sinon, je vais pas batailler des heures non plus. J'expliquerais que ce n'est pas possible et que s'ils veulent que ce soit possible, il faudra sortir de chéquier pour passer à la version full-SQL


[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
pradiergael Messages postés 13 Date d'inscription jeudi 7 mai 2009 Statut Membre Dernière intervention 11 décembre 2011
5 déc. 2011 à 22:48
ok.
pour le inner join, on peut le remplacer par une jointure à l'ancienne :

select xxx,yyy from Table where code not like '%-%'
union
select T.xxx,T.yyy from Table T , 
( select max(code) as code,code_seul 
  from ( select code, substring(code,1,charindex(code,'-')-1) as code_seul 
         from Table where code like '%-%') t1
  group by code_seul
) as TMP 
where T.code = TMP.code


tiens moi au courant.

bon courage.
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
6 déc. 2011 à 14:15
Effectivement, c'est inversé. Pourtant regarder MSDN, c'est la première chose que j'ai fait (certes en français donc traduction automatique) et de ce que j'avais compris, c'était dans le bons sens.

Maintenant ça marche, mais c'est remis en cause.
En effet pour 3-4 références, j'ai du -B,-C et -M. La requete, comme prévue me renvoie uniquement le -M, or le -M n'est pas indice dans ce cas précis mais une variante de la référence. Je devrait donc avoir la référence avec le -C et la référence avec le -M comme si c'était une référence sans indice.
J'ai un 10ène d'autres référence avec des cas similaires.

Perso, je refuse de faire des bidouilles et magouilles pour traiter les cas particuliers. donc je suis en attente de décision pour savoir si on re-référence les produits ou si on ne filtre pas les indices. Décision, qui, je le sais, n'arrivera jamais.

Donc j'enlève le filtre sur les indices en attendant.

Et je vous remercie pour votre aide





[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
6 déc. 2011 à 15:00
Il a l'air assez magique leur système de réf. ^^

Bon courage pour tes dev à venir
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
6 déc. 2011 à 15:11
Il est pas mal.
Mais surtout pas respecté.

C'est le problème quand trop de personnes ont le pouvoir décisionnaire, surtout quand elles ne se consultent pas, que chacune pense avoir le pourvoir tout puissant donné par Dieu lui-même.
Pour peu qu'une ou l'autre, suivant si elle est bien lunée ou pas, décide que la règle établie (par qui d'ailleurs) ne lui convient pas et fait comme elle a envie de faire.

Mon contrat se termine bientôt et je sais pas si je serais renouvelé.
Ça serait plutôt dans leur intérêt mais pas forcément dans le mien.

[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
6 déc. 2011 à 15:28
Faut leur proposer un service de consulting, ça manque d'orga ... et ça paie mieux
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
6 déc. 2011 à 16:18
Il y a des mots tabous dans cette boite : organisation, consulting, paye mieux, ...

Par contre, il y a une règle d'or : économies de bouts de chandelles sans vouloir voir les pertes de temps et d'argent qu'elles engendrent

[i][b]---- Sevyc64 (alias Casy) ----
[hr]# LE PARTAGE EST NOTRE FORCE #/b/i
0
pradiergael Messages postés 13 Date d'inscription jeudi 7 mai 2009 Statut Membre Dernière intervention 11 décembre 2011
8 déc. 2011 à 22:53
Un grand Merci à jopop pour avoir corrigé l'emploi de charindex.
j'ai fait ça de mémoire, sans vérifier ...

Finalement, le bon choix serait de refaire un nouveau référencement des produits.
Ce sera donc pour les calendes grecs
0
Rejoignez-nous