web-dev-qa-db-fra.com

Comment placer des zéros non significatifs pour les nombres inférieurs à 10 sans affecter ceux 10+?

Probablement une nouvelle question, mais ...

J'ai une table avec un champ VARCHAR contenant les nombres 1 à 300. Je dois placer un zéro de tête devant tout nombre inférieur à 10 tout en conservant le nombre d'origine s'il est 10 ou plus (c.-à-d. 1 = 01, 10 = 10 et 300 = 300).

SELECT DISTINCT RIGHT('0'+CONVERT(VARCHAR,[FacilityCode]),3) FROM...

Cela renvoie 1 = 01, 10 = 010 et 300 = 300 (en utilisant les mêmes exemples que ci-dessus)

EDIT: J'essaie de le faire dans une requête afin que je puisse faire des recherches sans modifier l'une ou l'autre table.

Quelqu'un peut-il donner un coup de main à un frère ici? Mon cerveau ne fonctionne tout simplement pas.

7
SnagQueensHubby

Le moyen le plus sûr est probablement d'ajouter des zéros uniquement lorsque la longueur de la colonne est de 1 caractère:

UPDATE
   Table
SET
   MyCol = '0' + MyCol
WHERE
   LEN(MyCol) = 1;

Cela couvrira tous les nombres inférieurs à 10 et ignorera également ceux qui ont déjà un 0 en tête.

MODIFIER

Pour sélectionner simplement les données, essayez:

SELECT
   MyColPadded = CASE WHEN LEN(MyCol) = 1 THEN '0' + MyCol ELSE MyCol END
FROM
   MyTable;
12
JNK

(il semble d'après votre exemple de code que vous utilisez MS SQL Server, mais vous devez ajouter une balise appropriée (et/ou un corps de texte) à votre question pour indiquer si c'est le cas, ou si ce n'est pas le SGBD que vous utilisez réellement)

N'importe laquelle des options ci-dessus devrait fonctionner correctement, j'utiliserais généralement le "préfixe 0, puis utiliser l'option RIGHT() comme vous l'avez, mais les autres sont parfaitement valides), mais un mot d'avertissement si vous attendez de nouvelles lignes (ou mises à jour des lignes existantes) pour contenir des nombres faibles - si cela est possible, vous vous retrouverez avec des valeurs non rembourrées. Pour éviter cela, vous pouvez utiliser un AFTER ou INSTEAD OF déclencheur pour forcer les valeurs au bon format au fur et à mesure de leur insertion/mise à jour pour empêcher le problème de revenir (sans avoir besoin de changer tous les points de code enregistrés dans cette table). Attention toutefois à vérifier les performances: les déclencheurs peuvent être très puissants mais il est également facile de créer un cauchemar avec eux.

1
David Spillett

Vous pouvez utiliser une déclaration de cas pour cela, si elle doit être formatée dans la base de données et que vous ne pouvez pas la conserver.

Select case when len(facilityCode) = 1 then 
          '0' else '' end + facilityCode as facilityCode
From YourTable

Il semble que vous le fassiez en tant que FK, si c'est le cas, vous ne pouvez pas avoir de contrainte FK sur un calcul. Pour faciliter la jointure, vous pouvez envisager une colonne calculée.

 ALTER TABLE yourTable 
    ADD cFacilityCode AS (
      case when len(facilityCode) = 1 then '0' else '' end + facilityCode);
1
jmoreno

Si vous vouliez un numéro à 3 chiffres, essayez ceci.

SELECT DISTINCT 
RIGHT('000'+CAST(ISNULL([FacilityCode],0) AS VARCHAR),3) 
FROM...

Résultat: 1 = 001, 10 = 010 et 300 = 300

Un nombre à 8 chiffres serait:

SELECT DISTINCT 
RIGHT('00000000'+CAST(ISNULL([FacilityCode],0) AS VARCHAR),8) 
FROM...

Résultat: 1 = 00000001, 10 = 00000010 et 300 = 00000300

Cela a l'avantage de travailler avec des sous-requêtes:

SELECT t_lac.FORCE_OVERWRITE
            , ISNULL(lay.ID,0) AS lacIDLayout
            --, t_lac.lacName
            , CASE WHEN t_lac.lacIDControlType = 18
                THEN 'PAN' + RIGHT('000' + CAST(ISNULL((SELECT ID FROM Layout l WHERE l.layName = t_lac.lacName),0) AS VARCHAR),3) + '_' + t_lac.lacName
                ELSE t_lac.lacName
                END AS lacName
            , t_lac.lacIDControlType
            , t_lac.lacStyle 
            FROM @T_LayoutControl t_lac
            LEFT JOIN Layout lay ON lay.layName = t_lac.layName
0
Gareth White