Numéro de client ID AUTOINCREMENT (001, 002, 003...)

Ce sujet est résolu
Default
,

Bonjour,

Actuellement sur la création d'un espace d'administration pour gérer mes clients je suis à la recherche d'un système efficace pour gérer les numéros de ces clients.

Ce que je veux

Le formatage que j'ai prévu pour le numéro du client est le suivant :

AA-000
Soit :
ANNEE - Numéro de 001 à 999 (Réprésentant le numéro du client dans l'année)

Plus concretement à chaque nouvel enregistrement d'un client, je souhaite que le numéro s'incrémente ainsi :

17-001 (Client 1 de 2017)
17-002 (Client 2 de 2017)
17-003 (...)
......
17-038
17-039
17-040
....
Nouvelle année
(Le compteur reprend à zéro)
....
18-001 (Client 1 de 2018)
18-002 (Client 2 de 2018)
18-003 (...)
......
18-038
etc.. etc.. pour chaque année.

Si je fais appel à vous c'est que j'aimerai savoir quel solution vous pourriez me conseiller et si possible me diriger sur une piste. J'ai pour idée de faire ceci avec l'id du client mais sa me parait compliqué.

Je m'explique :

L'année est facile à récupérer, mais c'est le reste qui pose problème. Je souhaite faire un autoincrement de cette facon : 001, 002, 003..., 024, 025.. etc.. Vous comprenez l'idée ? Avec 1 ou deux zero devant. Es possible ? De plus, si cela est possible il faudra que chaque année le compteur se remette à zéro pour la nouvelle année. 17-001, 17-002... (pour cette année), lorsque l'on passera 2018, les deux premiers chiffres seront naturellement 18 et la suite : 001, 002, 003 (on reprend à zero) etc... pour 2019, 2020...

J'espère avoir été assez clair, pas evident à expliquer !

Je remercie vivement d'avance celui ou celle qui pourra m'aiguiller un peu, car c'est fondamentale pour la suite de ma strucutre.

MERCI A VOUS :) :)

64 Réponse

1 3 4
53392
,

Bonjour

DELIMITER //
CREATE 
    DEFINER = 'pierre'@'%'
TRIGGER prostand_profil.clientx_b_i
    BEFORE INSERT
    ON prostand_profil.clientsx
    FOR EACH ROW
BEGIN
    DECLARE annee       char(2) ; -- default '17';
    DECLARE id_annee    char(4) ; -- default '0000';

    -- on part du principe que def_client peu contenir l'année 
   IF ISNULL(new.ref_client) or TRIM(new.ref_client) =''  THEN
      SET annee = CAST(YEAR(NOW())-2000 AS CHAR(2));
    ELSE
        SET annee = new.ref_client; 
    END IF;
    SET id_annee = (SELECT MAX(CAST(SUBSTRING(ref_client,4) AS UNSIGNED)) FROM clientsx WHERE LEFT(ref_client, 2) = annee)+1;
    set id_annee = if(isnull(id_annee),'0001',id_annee); 
    SET new.ref_client = concat(annee,'-',LPAD(id_annee,4,'0'));
END //
DELIMITER ;

1 tu enlèves le definer.
2 tu mets bien le nom de ta table y compris dans le FROM du SELECT.

et pour tester :

truncate table clientsx;
insert into clientsx (rs) values ('dupont');
insert into clientsx (rs,ref_client) values ('dupont2','16');
insert into clientsx (rs,ref_client) values ('dupont3','15');
insert into clientsx (rs) values ('dupont4');
insert into clientsx (rs) values ('dupont5');
insert into clientsx (rs,ref_client) values ('dupont6','16');
select * from clientsx; 

allééééeeee , bon courage ;)
@pluche.

Pierre

40917
, Il a répondu à ma question !

Bonsoir,

Je vois la chose comme ceci:
1/ Je récupère le dernier ID
2/ Je sépare cette ID en deux parties
3/ Je compare la 1ère partie à la date actuelle.
-> Si c'est égale alors, je récupère la deuxième partie et je l'incrémente de 1
-> Si c'est différent alors je remplace la 1ère partie par la bonne valeur et remet la deuxième partie à 1
4/ Je recompose le nouvel ID

Default
, Il a répondu à ma question !

Merci beaucoup pour ta réponse Carouge10 ! C'est une bonne piste à explorer.

Cependant mon intérrogation principal est es ce que je peux faire un autoincrement sur ''trois chiffres'' ? C'est à dire qu'au lieu d'avoir le classique : 1, 2, 3, 4, 5.... ce serait --> 001, 002, 003, 004 .... 038, 039... ? Et que sa revienne à zéro chaque année.

Ou alors je fais tous simplement pas d'autoincrement et je fais mon id ''maison'', si je peux appeler sa comme ca. Mais je voyais plus simple d'utiliser l'id de ma table comme le numéro du client.

112438
, Il a répondu à ma question !

hello, perso le plus "difficile" sera de reseter tes id chaque année, car pour le formatage c assez simple :

$an = 17;
$id = 15;
echo sprintf('%d-%2$03d', $an, $id);

la doc

40917
, Il a répondu à ma question !

Comme le dit Saibe, le formatage de l'id est simple et je ne sais si c'est possible de le faire automatiquement du côté SQL.
Par contre, comme vous le dites, il faudra le faire par le code. Le code sera une automatisation de la création de l'id en fonction des données.

L'id que vous souhaitez peut très bien servir de numéro de client puisqu'il sera unique et vous permetra de connaitre l'anciennété du client à un an près.

Default
, Il a répondu à ma question !

Un grand merci à vous deux pour vos réponses et votre aide !

Merci saibe, en faisant des recherches j'étais tombé sur cette doc et avais fais quelques essai mais avais pas très bien compris. C'est exactement le formatage que je recherchais ! Merci à toi ;-)

Maintenant c'est donc ok pour le formatage, je pense que je laisse tombé pour un reset de l'id chaque année (trop compliqué) et vais proceder avec le formatage.

Du coup, je ne fais pas d'autoincrement sur l'id (= le numéro du client) de ma table et je la laisse simplement en clé primaire. Juste ?

Après j'appliquerai l'idée de carouge10 (1/ Je récupère le dernier ID, 2/ Je sépare cette ID en deux parties...etc...). Sa devrai fonctionner !

Merci encore pour votre aide ! Je vais tester tout ça ce week end et metterai ce sujet comme résolu si tout se passe comme prévu :)

40917
, Il a répondu à ma question !

Oui l'auto-incremente, c'est à vous de le faire.
N'hésiter à poster le code pour l'id client, comme ça, cela pourra aider d'autre personne et puis vous aussi si vous bloquez sur un point du code.

112438
, Il a répondu à ma question !

@kamelzagger, avec plaiz ; cela dit pour plus de compréhension du formatage tu peux faire '%1d-%2$03d'
@Carouge10, perso, g po trop capté ton idée...
si le but est de conserver une ref chrono, sans enregistrement ext, basé sur des id autoincrement (primary j'imagine?) , c compliqué... sans parlé des désinscriptions ;) tu ne pourrais plus te baser sur un COUNT...
bref, je verrai davantage un ti fichier .log ou un champ d'une table app_options que tu incrémenterais et réseterais le 01.01.xx, en gros une variable ext...
je sais pas ;)

53392
, Il a répondu à ma question !

Salut,
Pourquoi ne pas faire un trigger ?
exemple :
DELIMITERS //

CREATE TRIGGER nom_de_ta_base.nom_de_ta_tatable_b_u
BEFORE INSERT
ON nom_de_ta_table
FOR EACH ROW
BEGIN
declare annee char(2) default '17';
declare id_annee char(4) default '0000';

set annee = year(now())-2000;
set id_annee = (select count(id) from tabable where nom_de_ton_champ_id like'%'+annee);

nom_de_ton_champ_id.new= concat(annee,'-',s,id_annee);

END

DELIMITER ;

@+

112438
, Il a répondu à ma question !

@Pierrot1 +1

53392
, Il a répondu à ma question !

Haaaa, la boulette :D

rectification :

remplacer

nom_de_ton_champ_id.new= concat(annee,'-',s,id_annee);

par

nom_de_ton_champ_id.new= concat(annee,'-',s,lpad(id_annee,4,'0'));

@pluche

Default
, Il a répondu à ma question !

Merci pour ta reponse @Pierrot1 !

Je ne connaissais pas cette methode de ''trigger'' mais j'ai l'impression que c'est une bonne piste.

En revanche, je t'avoue que je ne comprend pas tout (comme il s'agit de qqch de nouveau pour moi).

C'est un code que je dois executer sur le serveur sql (phpmyadmin) donc ? Ce qui permettra de ''formater'' ma table comme je le souhaite d'apres ce que j'ai compris ?

Je dois donc créer deux champs suplementaires : annee et id_annee ?

Ensuite avec ces deux valeurs je les rassembles pour creer l'id principal c'est ca ?

Ais-je bien tout compris ? ^^

Merci encore a toi !

53392
, Il a répondu à ma question !

Salut,
Non, annee et id_annee sont des variables.
normalement, tu remplaces juste les noms génériques que j'ai mis, et ça devrait marcher.
Tu lances cette requete une fois, et ça créer une procédure qui sera appelée avant chaque insertion dans ta table.

@pluche.

Pierre

Default
, Il a répondu à ma question !

Ha ok d'accord, c'est interessant !

Je vais tester tout ça cette semaine ;-)

PS : Dans ta rectification je vois ''Ipad'', faute de frappe ou c'est bien ca que je dois mettre ? ^^

MERCI A TOI ;-)

53392
, Il a répondu à ma question !

oui tu doit mettre LPAD ;)

tu doit mettre ça exactement :
set nom_de_ton_champ_id.new= concat(annee,'-',s,lpad(id_annee,4,'0'));

@pluche

112438
, Il a répondu à ma question !

heu, je me permet de rajouter que, même si l'utilisation d'un trigger semble être la bonne idée, tu ne pourras pas utiliser le code de @Pierrot01 tel kel...
d'une part il faudra que tu ais l'année d'enregistrement ds ta table, et d'autre part, comme je l'avais dit plus haut attention avec l'utilisation du COUNT si tu prévois de supprimer un user... à la limite ajoute un champ actif, et considère une suppression quand actif=0...

53392
, Il a répondu à ma question !

Pas la peine de mettre unchamp en plus.
Au lieude faireune select count tufais un select max ;)
@pluche

Default
, Il a répondu à ma question !

Oui c'est vrai que si je souhaite supprimer un client le COUNT ne sera plus juste. C'est un probleme.

De plus lors d'un auout d'un nouveau client j'aimerais egalement avoir la possibilité de choisir l'année (Si au cas ou j'ai oublié d'ajouter un client d'une année précedente) et si je ne choisis pas l'année c'est l'annee en cours qui est appliqué. Mais il me semble qu'avec ce systeme de triger, ce sera toujours l'annee en cours qui sera appliqué.

112438
, Il a répondu à ma question !

;) je sais pas comment tu fais set id_annee = (select count(id) from tabable where nom_de_ton_champ_id like'%'+annee); sans rajouter un champ annee ? et je rajouterais que l'utilisation de la variable nom_de_ton_champ_id n'est pas très pertinente... non ?

53392
, Il a répondu à ma question !

Il suffit de mettre dans l'id-formaté l'année et de tester dans le trigger
Du style :
IF id_formater > '' THEN
      faire les choses;
END IF

1 3 4