J'ai le tableau suivant:
==========================================================
| Name_Level_Class_Section | Phone Num |
==========================================================
| Jacky_1_B2_23 | 1122554455 |
| Johnhy_1_B2_24 | 1122554455 |
| Peter_2_A5_3 | 1122554455 |
==========================================================
Je pense à simplifier mon instruction SQL comme suit:
select
*,
substring(Name_Level_Class_Section,
CHARINDEX('_',Name_Level_Class_Section,
(CHARINDEX('_', Name_Level_Class_Section) + 1)) + 1,
CHARINDEX('_',Name_Level_Class_Section,
(CHARINDEX('_',Name_Level_Class_Section,
(CHARINDEX('_',Name_Level_Class_Section)+1))+1))-
CHARINDEX('_',Name_Level_Class_Section,
(CHARINDEX('_',Name_Level_Class_Section)+1))) as CLA
from
Bookings
order by
CLA asc, Name_Level_Class_Section asc
De sorte que lorsque j'exécute le SQL, cela me donnera le résultat suivant:
==========================================================
| Name_Level_Class_Section | Phone Num | CLA |
==========================================================
| Jacky_1_B2_23 | 1122554455 | B2 |
| Johnhy_1_B2_24 | 1122554455 | B2 |
| Peter_2_A5_3 | 1122554455 | A5 |
==========================================================
Existe-t-il un moyen de simplifier mon SQL?
Vous pouvez utiliser cross apply
et le troisième paramètre de charindex
pour obtenir la position des traits de soulignement.
declare @T table
(
Name_Level_Class_Section varchar(25)
)
insert into @T values
('Jacky_1_B2_23'),
('Johnhy_1_B2_24'),
('Peter_2_A5_3')
select substring(Name_Level_Class_Section, P2.Pos + 1, P3.Pos - P2.Pos - 1)
from @T
cross apply (select (charindex('_', Name_Level_Class_Section))) as P1(Pos)
cross apply (select (charindex('_', Name_Level_Class_Section, P1.Pos+1))) as P2(Pos)
cross apply (select (charindex('_', Name_Level_Class_Section, P2.Pos+1))) as P3(Pos)
Résultat:
-------------------------
B2
B2
A5
Mise à jour: En utilisant votre table, la requête ressemblerait à ceci:
select *,
substring(Name_Level_Class_Section, P2.Pos + 1, P3.Pos - P2.Pos - 1) as CLA
from Bookings
cross apply (select (charindex('_', Name_Level_Class_Section))) as P1(Pos)
cross apply (select (charindex('_', Name_Level_Class_Section, P1.Pos+1))) as P2(Pos)
cross apply (select (charindex('_', Name_Level_Class_Section, P2.Pos+1))) as P3(Pos)
order by CLA asc,
Name_Level_Class_Section asc
Mise à jour 2:
Si vous savez avec certitude que votre valeur ne contient jamais de point .
et que c'est toujours un nom en quatre parties que vous pouvez utiliser parsename .
select *,
parsename(replace(Name_Level_Class_Section, '_', '.'), 2) as CLA
from Bookings
order by CLA asc,
Name_Level_Class_Section asc
Vous pouvez utiliser l'UDF suivant (fonction en ligne plutôt que scalaire)
CREATE FUNCTION dbo.INSTR
(
@str VARCHAR(8000),
@Substr VARCHAR(1000),
@start INT ,
@Occurance INT
)
RETURNS TABLE
AS
RETURN
WITH Tally (n) AS
(
SELECT TOP (LEN(@str)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(n)
)
, Find_N_STR as
(
SELECT
CASE WHEN DENSE_RANK() OVER(PARTITION BY @Substr ORDER BY (CHARINDEX(@Substr ,@STR ,N))) = @Occurance
THEN MAX(N-@start +1) OVER (PARTITION BY CHARINDEX(@Substr ,@STR ,N) )
ELSE 0
END [Loc]
FROM Tally
WHERE CHARINDEX(@Substr ,@STR ,N) > 0
)
SELECT Loc= MAX(Loc)
FROM Find_N_STR
WHERE Loc > 0
Comment utiliser:
declare @T table
(
Name_Level_Class_Section varchar(25)
)
insert into @T values
('Jacky_1_B2_23'),
('Johnhy_1_B2_24'),
('Peter_2_A5_3')
select t.Name_Level_Class_Section , l.Loc
from @t t
cross apply dbo.INSTR (t.Name_Level_Class_Section, '_',1,2) l
PARSENAME a été mentionné comme solution si la chaîne ne contenait pas de point. S'il utilise cette modification pour changer les périodes en quelque chose d'autre, puis analysez la valeur, puis remettez les périodes
Select REPLACE(PARSENAME(REPLACE(REPLACE('Jacky_1_B2.00_23','.','~'), '_', '.'), 2),'~','.')