Impostazione dello schema di MS SQL Server 2014 :
CREATE TABLE table_name ( name VARCHAR(50) );INSERT INTO table_nameSELECT 'AE 344592001H 6186694' UNION ALLSELECT 'AE_161038002_6044777' UNION ALLSELECT 'BC_VIVS_HNB011A_1WAM' UNION ALLSELECT 'BC_56230A_30SP' UNION ALLSELECT 'CG_3334902_NETWK_ ACTLM_3334912' UNION ALLSELECT 'CG_3334574_HMO1_CORACT_3334575 ' UNION ALLSELECT 'CG_3207160_POSC_1502AH_3207161' UNION ALLSELECT 'UH_141015_RHM' UNION ALLSELECT 'UH_127757_RIV' UNION ALLSELECT 'UH 523725 RIV' UNION ALLSELECT 'BS_W0055785_C500_M0005672';
Query 1 :
CON Nomi ( lvl, nome, rimanente, idx ) AS ( SELECT 1, nome, nome, CHARINDEX( '_', nome ) FROM table_name UNION ALL SELECT lvl+1, nome, SUBSTRING(restante,idx +1,LEN(restante)-idx), CASE WHEN CHARINDEX( '_', rimanente, idx+1 ) =0 THEN 0 ELSE CHARINDEX( '_', rimanente, idx+1 ) - idx END FROM Nomi WHERE idx> 0) SELEZIONA Nome, MAX( CASE QUANDO lvl =3 AND ( Nome LIKE 'CG%' OR idx =0 ) THEN rimanente QUANDO lvl =3 THEN SUBSTRING( rimanente, 1, idx - 1 ) END ) AS OPT, MAX( CASE QUANDO lvl =2 AND ( Nome LIKE 'CG%' OR idx =0 ) ALLORA rimanente QUANDO lvl =2 ALLORA SUBSTRING( rimanente, 1, idx - 1 ) END ) COME Nome2DA NomiGRUPPO PER Nome
| Nome | OPT | Nome2 ||---------------------------------|------------- ---------|----------------||| AE 344592001H 6186694 | (nullo) | (nulla) || AE_161038002_6044777 | 6044777 | 161038002 || BC_56230A_30SP | 30SP | 56230A || BC_VIVS_HNB011A_1WAM | HNB011A | VIVS || BS_W0055785_C500_M0005672 | C500 | W0055785 || CG_3207160_POSC_1502AH_3207161 | POSC_1502AH_3207161 | 3207160_POSC_1502AH_3207161 || CG_3334574_HMO1_CORACT_3334575 | HMO1_CORACT_3334575 | 3334574_HMO1_CORACT_3334575 || CG_3334902_NETWK_ ACTLM_3334912 | RETE_ACTLM_3334912 | 3334902_NETWK_ ACTLM_3334912 || UH 523725 RIV | (nullo) | (nulla) || UH_127757_RIV | RIV | 127757 || UH_141015_RHM | RHM | 141015 |
Query 2 :
CHARINDEX( expressionToFind, expressionToSerach[, startIndex] )
può essere utilizzato per trovare le istanze di _
nella parola.
CHARINDEX( '_', nome )
troverà l'indice della prima istanza di un_
.CHARINDEX( '_', nome, CHARINDEX( '_', nome ) + 1 )
troverà l'indice della seconda istanza di un_
o restituirà0
se non ci sono due_
caratteri.CHARINDEX( '_', nome, CHARINDEX( '_', nome, CHARINDEX( '_', nome ) + 1 ) + 1)
troverà l'indice della terza istanza di un_
o restituirà0
se non ci sono tre_
caratteri.
Annidandolo in una selezione interna, puoi usarlo per ottenere il SUBSTRING
appropriato s in una selezione esterna come questa:
SELECT name, CASE WHEN idx2> idx1 AND ( Name LIKE 'CG%' OR idx3 =0 )THEN SUBSTRING( name, idx2 + 1, LEN( name ) ) WHEN idx3> idx2 THEN SUBSTRING( nome, idx2 + 1, idx3 - idx2 - 1 ) END AS OPT, CASE WHEN name LIKE 'CG%' THEN SUBSTRING( name, idx1 + 1, LEN( name ) ) WHEN idx2> idx1 THEN SUBSTRING( name, idx1 + 1, idx2 - idx1 - 1 ) END AS Name2FROM ( SELECT name, CHARINDEX( '_', name ) AS idx1, CHARINDEX( '_', name, CHARINDEX( '_', name ) + 1 ) AS idx2, CHARINDEX( '_' , nome, CHARINDEX( '_', nome, CHARINDEX( '_', nome ) + 1 ) + 1 ) AS idx3 FROM table_name) t
| nome | OPT | Nome2 ||---------------------------------|------------- ---------|----------------||| AE 344592001H 6186694 | (nullo) | (nulla) || AE_161038002_6044777 | 6044777 | 161038002 || BC_VIVS_HNB011A_1WAM | HNB011A | VIVS || BC_56230A_30SP | 30SP | 56230A || CG_3334902_NETWK_ ACTLM_3334912 | RETE_ACTLM_3334912 | 3334902_NETWK_ ACTLM_3334912 || CG_3334574_HMO1_CORACT_3334575 | HMO1_CORACT_3334575 | 3334574_HMO1_CORACT_3334575 || CG_3207160_POSC_1502AH_3207161 | POSC_1502AH_3207161 | 3207160_POSC_1502AH_3207161 || UH_141015_RHM | RHM | 141015 || UH_127757_RIV | RIV | 127757 || UH 523725 RIV | (nullo) | (nulla) || BS_W0055785_C500_M0005672 | C500 | W0055785 |