Ceci est une question T-SQL, j'utilise Microsoft SQL Server 2014. Je joins trois tables, ce qui est très simple. La partie délicate est la suivante: l'une des variables, SubtotalKey, prend la forme 'ABD_1999_MAE_1'. Je voudrais diviser cette variable en ses quatre composants, délimités par le trait de soulignement, et inclure les quatre colonnes dans ma sortie à un point spécifique dans la requête. J'ai une solution réalisable qui utilise une fonction scalaire. Praticable dans le sens où il fait ce que je viens de décrire ... mais il y a des problèmes de performance qui le rendent inutilisable. Depuis, j'ai converti la fonction scalaire en une fonction table et j'utilise 'outer apply' comme solution. Malheureusement, cela se traduit par 4 lignes dans la sortie par résultat ligne de la jointure. Je ne sais pas où aller à partir d'ici - j'ai essayé le pivot, mais le pivot a besoin de colonnes numériques pour pivoter, je pense. Tous aident beaucoup apprécié.T-SQL - Comment diviser une variable en 4 colonnes pour la sortie?
La fonction de valeur de table dans le code ci-dessous, ufn_SplitString, divisera la chaîne ci-dessus en une table avec 1 colonne et 4 lignes. Les 4 lignes contiennent les valeurs, respectivement, ABD, 1999, MAE, 1.
Pour les besoins de cette question, il y a 4 éléments dans SubtotalKey, mais en réalité, le nombre sera variable. Une solution est-elle possible, si je ne sais pas à l'avance quel sera le nombre de colonnes supplémentaires requises? Voici mon code à ce jour:
SELECT
t1.t_proj AS time_period,
ufn.item,
t3.AnnClaimVal AS annuity_outgo_smbel,
t3.DeathClaimVal AS death_outgo_smbel,
t2.SolvSurvXCF AS annuity_outgo_reins,
t2.SolvDeathXCF AS death_outgo_reins,
t2.ReinSwapXCF AS mortswap_fixedleg_payment,
t3.ExpenseValXCF AS ren_exp,
t1.InvExpSCF AS inv_exp,
t1.InvExpReinSCF AS inv_exp_reins
FROM [sch_ImmAnn].[viw_mdlEV_Formulae] t1
INNER JOIN [sch_ImmAnn].[viw_mdl_Formulae] t2
ON t1.t_proj = t2.t_proj AND t1._SubtotalKey = t2._SubtotalKey AND t1._Scenario = t2._Scenario AND t1._ExecRun_UID = t2._ExecRun_UID
INNER JOIN [sch_ImmAnn].[viw_mdlValue_Formulae] t3
ON t1.t_proj = t3.t_proj AND t1._SubtotalKey = t3._SubtotalKey AND t1._Scenario = t3._Scenario AND t1._ExecRun_UID = t3._ExecRun_UID
OUTER APPLY sch_Common.ufn_SplitString(t1._SubtotalKey,'_') ufn
WHERE t1._ExecRun_UID = @ExecUID AND t1._Scenario = @Scenario
AND t1.t_proj >= 0 AND t1.t_proj <= 650
ORDER BY SubtotalKey, time_period
Voici quelques exemples de données pour t1:
t_proj SubtotalKey Scenario ExecRun_UID InvExpSCF InvExpReinSCF
1 ABD_1999_MAE_1 1 36FA21C8 5334.44 37.88
2 EMM_E12_MAE_3 1 36FA21C8 1894.88 1298.3
3 XYZ_2008_MAE_1 1 36FA21C8 12.99 10009.33
Voici quelques exemples de données pour t2:
t_proj SubtotalKey Scenario ExecRun_UID SolvSurvXCF SolvDeathXCF ReinSwap
1 ABD_1999_MAE_1 1 36FA21C8 543.88 12.33 1.2
2 EMM_E12_MAE_3 1 36FA21C8 2985.11 59.31 4.6
3 XYZ_2008_MAE_1 1 36FA21C8 309999.12 111.33 9.7
Voici quelques exemples de données pour t3:
t_proj SubtotalKey Scenario ExecRun_UID ExpenseValXCF AnnClaimVal DeathClaimVal
1 ABD_1999_MAE_1 1 36FA21C8 100 901 678
2 EMM_E12_MAE_3 1 36FA21C8 200 492 121
3 XYZ_2008_MAE_1 1 36FA21C8 554 510 144
Voici la sortie désirée:
t_proj Col1 Col2 Col3 Col4 Scenario ExecRun_UID InvExpSCF InvExpReinSCF SolvSurvXCF SolvDeathXCF ReinSwap ExpenseValXCF AnnClaimVal DeathClaimVal
1 ABD 1999 MAE 1 1 36FA21C8 5334.44 37.88 543.88 12.33 1.2 100 901 678
2 EMM E12 MAE 1 1 36FA21C8 1894.88 1298.3 2985.11 59.31 4.6 200 492 121
3 XYZ 2008 MAE 1 1 36FA21C8 12.99 10009.33 309999.12 111.33 9.7 554 510 144
Code de fonction:
ALTER FUNCTION [sch_Common].[ufn_SplitString]
(
@Input NVARCHAR(MAX),
@Character CHAR(1)
)
RETURNS @Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE @StartIndex INT, @EndIndex INT
SET @StartIndex = 1
IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
BEGIN
SET @Input = @Input + @Character
END
WHILE CHARINDEX(@Character, @Input) > 0
BEGIN
SET @EndIndex = CHARINDEX(@Character, @Input)
INSERT INTO @Output(Item)
SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)
SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
END
RETURN
END
Vous devez faire une croix onglet dynamique ou dynamique, car pivot vous ne disposez pas d'un nombre fixe de colonnes à chaque fois que cette exécution. –
Cette question n'est pas la même que l'autre, car je demande s'il est possible de diviser une variable existante en plusieurs variables. L'autre question ne traite pas de cela. Il y a une similitude dans le fait que je ne sais pas finalement combien de colonnes il y aura. – mediaeval
Vous avez déclaré que vous divisez ces valeurs et que votre code comporte une fonction de division. Maintenant, vous voulez faire ces lignes en colonnes à droite? C'est la technique décrite dans la question que j'ai marquée comme doublon. Je vais rouvrir cela mais je ne suis pas vraiment sûr de votre question. –