Domanda

Devo filtrare i dati spazzatura nella tabella SQL (SQL Server 2008). Devo identificare questi record ed estrarli.

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

{Non sono ammessi spazi vuoti}

Fondamentalmente, un record pulito sarà simile al seguente:

  • T1234, U2468, K123, P50054 (4 esempi di record)

I dati inutili si presentano così:

  • T12 .., .T12, MARK, TP1, SP2, BFGL, BFPL (7 esempi di record)

Qualcuno può aiutare con una query SQL a fare un metodo SINISTRA e DESTRA ed estrarre quei caratteri e fare un LIKE IN o qualcosa del genere?

Una funzione sarebbe fantastica!

È stato utile?

Soluzione

Quanto segue dovrebbe funzionare in alcuni sistemi diversi:

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

Questo approccio corrisponderà effettivamente a P2343, P23423JUNK e altri testi simili ma richiede che il formato sia A0000 *.

Ora, se l'OP implica che un formato di 1a posizione è un carattere e tutte le posizioni successive sono numeriche, come in A0 +, utilizzare quindi quanto segue (in SQL Server e molti altri sistemi di database):

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

Per incorporare questo in una funzione di SQL Server 2008, poiché questo sembra essere quello che ti piacerebbe di più, puoi scrivere:

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

... e chiamalo così:

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

... questa query deve cambiare per le query Oracle perché Oracle non sembra supportare la notazione di parentesi nelle clausole LIKE:

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

Questa è l'espansione che gbn sta facendo nella sua risposta, ma queste versioni consentono di variare la lunghezza delle stringhe senza le condizioni OR.

MODIFICA : aggiornato per supportare esempi in SQL Server e Oracle per garantire il formato A0 +, in modo che A1324, A2342388 e P2342 corrispondano ma A2342JUNK e A234 non lo fanno.

Il codice REGEXP_LIKE di Oracle è stato preso in prestito dalla posta di Mark ma aggiornato per supportare 4 o più cifre numeriche.

Aggiunto un approccio personalizzato di SQL Server 2008 che implementa queste tecniche.

)

Questa è l'espansione che gbn sta facendo nella sua risposta, ma queste versioni consentono di variare la lunghezza delle stringhe senza le condizioni OR.

MODIFICA : aggiornato per supportare esempi in SQL Server e Oracle per garantire il formato A0 +, in modo che A1324, A2342388 e P2342 corrispondano ma A2342JUNK e A234 non lo fanno.

Il codice REGEXP_LIKE di Oracle è stato preso in prestito dalla posta di Mark ma aggiornato per supportare 4 o più cifre numeriche.

Aggiunto un approccio personalizzato di SQL Server 2008 che implementa queste tecniche.

Altri suggerimenti

Dipende dal tuo database. Molti hanno funzioni regex (nota esempi non testati quindi controlla)

es. Oracle

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

Sybase utilizza LIKE

)

Sybase utilizza LIKE

Dato che stai permettendo tra 3 e 6 cifre per il numero nei tuoi esempi, probabilmente è meglio usare la funzione ISNUMERIC () dal 2 ° carattere in poi:

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 '%.%'

Per ulteriori informazioni, consultare la funzione ISNUMERIC su MSDN.

Nota anche che:

  • Ho limitato la seconda parte con il numero massimo di 50 caratteri, modificalo in base alle tue esigenze.
  • A rigor di termini, dovresti controllare i simboli di valuta ecc., come ISNUMERIC consente loro, così come +/- e alcuni altri

Un'opzione migliore potrebbe essere quella di creare una funzione che controlli che ciascun carattere dopo il primo sia compreso tra 0 e 9 (o 1 e 0 se si utilizzano codici ASCII).

Non è possibile utilizzare le espressioni regolari in SQL Server, quindi è necessario utilizzare OR. Correzione della risposta di David Andres ...

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 risposta di David consente " D1234junk " attraverso

Devi anche solo " [A-Z] " se non hai la distinzione tra maiuscole e minuscole

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top