2009-09-13 3 views
1

J'ai besoin de filtrer les données indésirables dans la table SQL (SQL Server 2008). J'ai besoin d'identifier ces enregistrements et de les retirer.Requête SQL - LEFT 1 = char, RIGHT 3-5 = nombres dans le nom

  • Char [0] = A..Z, A..Z
  • Char [1] = 0..9
  • Char [2] = 0..9
  • Char [3 ] = 0..9
  • Char [4] = 0..9

{Aucun blanc autorisé}

Fondamentalement, une nouvelle propre cordon ressemblera à ceci:

  • T1234, U2468, K123, P50054 (4 exemples d'enregistrement)

données indésirable ressemble à ceci:

  • T12 .., .T12, MARK , TP1, SP2, BFGL, BFPL (7 exemples d'enregistrement)

Quelqu'un peut-il s'il vous plaît aider avec une requête SQL pour faire une méthode GAUCHE et DROITE et extraire ces caractères, et faire un I comme N ou quelque chose?

Une fonction serait géniale cependant!

+0

Riann: ajouté un Fonction SQL Server 2008 que vous pouvez utiliser si vous en avez besoin. –

Répondre

4

Ce qui suit devrait fonctionner dans quelques systèmes différents:

SELECT * 
FROM TheTable 
WHERE Data LIKE '[A-Za-z][0-9][0-9][0-9][0-9]%' 
AND Data NOT LIKE '% %' 

Cette approche fait correspondre P2343, P23423JUNK, et un autre texte similaire, mais exige que le format est A0000 *.

Maintenant, si l'OP implique un format de la 1ère position est un personnage et toutes les positions suivantes sont numériques, comme dans A0 +, puis utilisez les éléments suivants (dans SQL Server et beaucoup d'autres systèmes de base de données):

SELECT * 
FROM TheTable 
WHERE SUBSTRING(Data, 1, 1) LIKE '[A-Za-z]' 
AND SUBSTRING(Data, 2, LEN(Data) - 1) NOT LIKE '%[^0-9]%' 
AND LEN(Data) >= 5 

pour intégrer dans une fonction SQL Server 2008, puisque cela semble être ce que vous voulez plus, vous pouvez écrire:

CREATE FUNCTION ufn_IsProperFormat(@data VARCHAR(50)) 
RETURNS BIT 
AS 
BEGIN 
    RETURN 
    CASE 
     WHEN SUBSTRING(@Data, 1, 1) LIKE '[A-Za-z]' 
     AND SUBSTRING(@Data, 2, LEN(@Data) - 1) NOT LIKE '%[^0-9]%' 
     AND LEN(@Data) >= 5 THEN 1 
     ELSE 0 
     END 
END 

... et appeler en elle comme ceci:

SELECT * 
FROM TheTable 
WHERE dbo.ufn_IsProperFormat(Data) = 1 

...cette requête doit changer pour les requêtes Oracle car Oracle ne semble pas soutenir la notation crochets dans les clauses LIKE:

SELECT * 
FROM TheTable 
WHERE REGEXP_LIKE(Data, '^[A-za-z]\d{4,}$') 

Ceci est le gbn d'expansion fait dans sa réponse, mais ces versions permettent de faire varier la longueur des chaînes sans OU conditions.

EDIT: Mise à jour pour soutenir des exemples dans SQL Server et Oracle pour assurer le format A0 +, de sorte que A1324, A2342388 et match P2342 mais A2342JUNK et A234 ne le font pas.

Le code Oracle REGEXP_LIKE a été emprunté à la publication de Mark, mais mis à jour pour prendre en charge au moins 4 chiffres numériques.

Ajout d'une approche SQL Server 2008 personnalisée qui implémente ces techniques.

+0

Ce qu'il accepte "D1234junk" – gbn

+0

@gbn: Vous avez raison, mais je ne pouvais pas dire être le PO si cela est permis ou non. Je sais que la chaîne peut contenir plus de cinq caractères, mais l'étendue des valeurs peut être jugée à partir de la publication. En outre, j'ai modifié le message pour gérer la règle sur les espaces vides. Ce n'est pas propre, mais c'est conforme. –

2

Dépend de votre base de données. Beaucoup ont des fonctions regex (notez les exemples non testés donc cochez)

par exemple. Oracle

SELECT x 
FROM table 
WHERE REGEXP_LIKE(x, '^[A-za-z][:digit:]{4}$') 

Sybase utilise COMME

+0

Je crois que REGEXP_LIKE est une convention Oracle, donc cela dépend vraiment du système utilisé. –

+0

@Mark: J'ai emprunté ceci dans ma propre réponse. C'est bon et ça fonctionne au sein d'Oracle. Je l'ai étendu à {4,} pour impliquer quatre ou plusieurs correspondances afin que les chaînes comme P1234 et P123423432 correspondent également. –

2

Étant donné que vous permettant entre 3 et 6 chiffres pour le numéro dans vos exemples, alors il est probablement préférable d'utiliser la fonction sur le 2ème caractère partir ISNUMERIC():

SELECT * 
FROM TheTable 
-- start with a letter 
WHERE Data LIKE '[A-Za-z]%' 
    -- everything from 2nd character onwards is a number 
    AND ISNUMERIC(SUBSTRING(Data, 2, 50)) = 1 
    -- number doesn't have a decimal place 
    AND Data NOT LIKE '%.%' 

Pour plus d'informations consulter la fonction ISNUMERIC sur MSDN.

Notez également que:

  • J'ai limité la 2ème partie du nombre de 50 caractères maximum, modifier ce pour répondre à vos besoins.
  • vous devriez vérifier à proprement parler des symboles monétaires etc, comme ISNUMERIC leur permet, ainsi que +/- et quelques autres

Une meilleure option pourrait être de créer une fonction qui vérifie que chaque caractère après la première est compris entre 0 et 9 (ou 1 et 0 si vous utilisez des codes ASCII).

+0

Cela pourrait fonctionner avec un changement de ISNUMERIC (SUBSTRING (données, 2, 50)) à ISNUMERIC (SUBSTRING (données, 2, LEN (données) - 1)). Vous devez également vérifier la longueur de la chaîne, qui semble nécessiter au moins cinq caractères. –

2

Vous ne pouvez pas utiliser les expressions régulières dans SQL Server, vous devez donc utiliser OR. Correction David Andres réponse ...

WHERE 
    (
    Data LIKE '[A-Za-z][0-9][0-9][0-9]' 
    OR 
    Data LIKE '[A-Za-z][0-9][0-9][0-9][0-9]' 
    OR 
    Data LIKE '[A-Za-z][0-9][0-9][0-9][0-9][0-9]' 
    ) 

La réponse de David permet "D1234junk" par

Vous avez également besoin que "[AZ]" si vous n'avez pas la casse

+0

gbn: Voir l'OP où "P50054" est considéré comme valide mais comporte également plus de cinq caractères. Votre approche est valable mais nécessite une expansion infinie. –

+0

@David: Vous avez vraiment besoin d'une regex pour autoriser les caractères numériques non définis sur la droite.Cependant, le titre dit 3-5 nombres sur la droite donc cette approche fera ce qui est attendu (en ignorant les valeurs NULL) – gbn

+0

@gbn: Jetez un oeil à ma réponse mise à jour. Dans les systèmes qui prennent en charge la notation entre parenthèses dans l'opérateur like (ce qui n'est apparemment pas le cas d'Oracle), vous pouvez utiliser NOT LIKE '% [^ 0-9]%' pour vous assurer que seuls les chiffres sont valides. –

Questions connexes