2
votes

LPAD sans rognage dans mysql

J'essaie de trouver un moyen d'ajouter 0 au début d'un identifiant sans le couper:

J'utilise actuellement LPAD (id, 4, "0") qui fonctionne bien jusqu'à 9999

  • Requête: SELECT LPAD (12345,4, "0");
  • Résultat exclu: 12345
  • Résultat: 1234

Je recherche une requête qui exécute LPAD (id, MAX (LENGTH (id), 4), "0")

J'ai trouvé SELECT IF (LENGTH (12345)> 4, 12345, LPAD (12345, 4, "0")); mais je préférerais si le 4 était dans un seul endroit (pour le rendre plus facile, utilisez-le ailleurs).

  • Existe-t-il une fonction intégrée qui fait ce que je recherche?
  • Ou existe-t-il une alternative à la fonction MAX () qui fonctionnerait dans cette situation?
  • Ou devrais-je m'en tenir à la solution IF (LENGTH) et ses inconvénients?

Modifier:

ZEROFILL ne répond pas à mes besoins car j'ai également besoin de l'identifiant sans 0 s. J'utilise principalement l'ID sans le LPAD () , mais quand je le fais, je l'utilise avec un préfixe: CONCAT ("PFX", LPAD (id, 4, "0"))

Merci pour votre aide

PS: s'il vous plaît dites-moi si je fais quelque chose de mal, c'est la première fois que je demande ici.


1 commentaires

La question est bien, bienvenue à SO!


4 Réponses :


1
votes

Demandez-vous pourquoi un nombre aurait besoin de zéros non significatifs. Aucun nombre en mathématiques pratiques et théoriques n'a besoin de zéros non significatifs.

Vous voulez peut-être visionner quelque chose, et ne pas travailler avec le résultat comme un nombre réel. Dans ce cas, vous pouvez soit déclarer le champ dans la table ZEROFILL et le sélectionner converti en char: SELECT CONVERT (id, CHAR); .

Autre que cela, le seul moyen est un mélange de CONCAT () et LENGTH () , de cette façon vous évitez de dépouiller l'ID à la valeur dans LPAD () .


2 commentaires

Merci pour la réponse, ZEROFILL ne correspond pas à mes besoins car j'ai également besoin de l'identifiant sans 0 s. Le cas d'utilisation principal est avec un préfixe: COM0123 . Je ne comprends pas parfaitement comment utiliser CONCAT () avec un montant variable de 0


@PierreLezan Je pense que vous devez d'abord comprendre la différence entre un nombre / entier et une chaîne / caractère. Il n'y a aucune différence sémantique / mathématique entre 000012 et 12 et n'affecte pas non plus l'intégrité lorsqu'il est utilisé comme un nombre.



2
votes

Vous pouvez saisir la longueur d'un champ int et définir le remplissage à zéro comme ceci:

MariaDB []>     SELECT
    ->       id,
    ->       SUBSTRING( CONCAT('000000',Numbers),- GREATEST(LENGTH(Numbers),5))
    ->     FROM num;
+----+--------------------------------------------------------------------+
| id | SUBSTRING( CONCAT('000000',Numbers),- GREATEST(LENGTH(Numbers),5)) |
+----+--------------------------------------------------------------------+
|  1 | 00001                                                              |
|  2 | 00022                                                              |
|  3 | 123456                                                             |
+----+--------------------------------------------------------------------+
3 rows in set (0.001 sec)

MariaDB []>

Insérer des valeurs:

SELECT 
  id,
  SUBSTRING( CONCAT('000000',Numbers),- GREATEST(LENGTH(Numbers),5))
FROM num;

Voir le résultat:

MariaDB []> select * from num;
+----+---------+
| id | Numbers |
+----+---------+
|  1 |   00001 |
|  2 |   00022 |
|  3 |  123456 |
+----+---------+
3 rows in set (0.000 sec)

MariaDB []>

sans remplissage à zéro, vous pouvez le calculer comme:

INSERT INTO `num` (`id`, `Numbers`)
VALUES
    (1, 1),
    (2, 22),
    (3, 123456);

Résultat:

CREATE TABLE `num` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `Numbers` int(5) unsigned zerofill DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


2 commentaires

Merci pour la réponse, ZEROFILL ne correspond pas à mes besoins car j'ai également besoin de l'identifiant sans 0 ailleurs. (Je viens de mettre à jour ma question).


@Pierre Lezan - J'ai changé ma réponse



0
votes

LPAD

Vous pouvez y parvenir avec un REGEXP_REPLACE pour faire un équivalent LPAD mais sans tronquer le résultat. Si vous voulez une longueur minimale de 4 et un remplissage avec 0, vous pouvez faire:

REGEXP_REPLACE(CONCAT(id, '0000'), '^(.{4,}?)0{0,4}$', '\\1')

Vous pouvez l'adapter en remplaçant '0000' par REPEAT ('0', 4) pour le faire par programmation. Le principal avantage de cette approche est de ne pas répéter la chose rembourrée. Dans mes cas d'utilisation, je peux avoir des choses très longues et complexes que je ne veux pas dupliquer pour les remplir uniquement, donc ce fragment de code fait son travail.

RPAD

Pour ceux qui ont le problème de RPAD , vous avez besoin d'un modèle très proche:

REGEXP_REPLACE(CONCAT('0000', id), '^0{0,4}(.{4,})$', '\\1')

Les deux blocs du modèle sont essentiellement inversés mais vous pouvez voir . {4,}? au lieu de . {4,} . C'est pour régler la gourmandise sur paresseux pour le quantificateur {4,} . C'est nécessaire ici.


0 commentaires

1
votes

Eh bien, j'ai eu un problème similaire avec LPAD, il tronquait le nombre à sa longueur de pad. Selon https://dev.mysql.com/ doc / refman / 8.0 / en / string-functions.html # function_lpad c'est le résultat attendu.

Pour autant que je sache, personne n'a mentionné la réponse qui a résolu mon même problème:

LPAD(id, GREATEST(LENGTH(id), 4), "0")

Cela fonctionne comme prévu. Remplit tout id de moins de 4 caractères avec 0 et renvoie les id inchangés de plus de 4 caractères.

Je pars ma réponse ici pour d'autres personnes, qui trouveront cette question dans le futur.


3 commentaires

C'est ce que j'ai fini par faire, comme conseillé à la fin de la réponse acceptée


Je ne vois aucune réponse avec la solution fournie par moi. Tout le monde utilise un mélange de SUBSTRING , de CONCAT ou de REGEXP_REPLACE . J'ai posté cette réponse, donc toute autre personne qui trouve cette question (comme moi) aura peu de possibilités :)


Mon mauvais, j'ai mal lu la réponse de Daniel, ta réponse était ce que je cherchais à l'époque