SQL Everyday – beräkna bostadskostnad och nettokapital
Sunday, July 13th, 2014Hej!
Här om dagen skapade jag en stored procedure för att räkna ut bostadskostnaden mellan en hyresrätt och bostadsrätt, då jag stod i valet och kvalet om vad jag ville köpa eller hyra lägenhet. Det finns självklart andra överväganden som inte kan tas med i beräkningen; läge, standard, utrustning, utsikt, intresse av renovering/inredning och mycket annat. Sen kanske man inte alltid kan välja, men om man kan välja kan denna sql-procedur hjälpa dig att få en översikt om hur kostnader, men också nettokapital förändras över en längre tid. Nettokapitalet bygger på sparande i sparkonto, värdepapper och bostadsvärde och räknas även det ut i proceduren.
För att få rätt data in i proceduren och inte ge någon slags översvämning i antalet inputparametrar så har jag lagt delar av dessa variabler i två styrtabeller: bostad och scenario. Bostadstabellen bygger på förväntade kostnader, ursprungsvärderingar och insatser. Eftersom ingen vet hur börsen, räntan, inflationen och värderingar ändras över tid så kan man behöva spela upp flera scenarion, detta läggs i scenariotabellen.
Bostad
CREATE TABLE [dbo].[Bostad]( [BostadId] [int] IDENTITY(1,1) NOT NULL, [BostadNamn] [varchar](100) NULL, [TypAvBostad] [varchar](20) NULL, [BostadInköpskostnad] [money] NULL, [BostadInsats] [money] NULL, [NettoInkomstPerMånad] [money] NULL, [HyraEllerAvgiftPerMånad] [money] NULL, [ÖverlåtelseAvgift] [money] NULL, [MäklarArvodeIProcentVidFörsäljning] [money] NULL, [AvdragIProcentVidFörsäljning] [decimal](6, 2) NULL, [UnderhållPerMånad] [money] NULL, [VinstavdragIProcent] [decimal](6, 2) NULL, [AmorteringPerMånad] [money] NULL, [SparandeSparkontoInsats] [money] NULL, [SparandeMånadssparProcentPerNettoAllt] [money] NULL, [AktierInsats] [money] NULL, [AktierMånadssparProcentPerNettoAllt] [money] NULL, [FonderInsats] [money] NULL, [FonderMånadssparProcentPerNettoAllt] [money] NULL, [ElperMånad] [money] NULL, [FörsäkringperMånad] [money] NULL, [BredbandperMånad] [money] NULL, [TvperMånad] [money] NULL, [MatPerMånad] [money] NULL, [ÖvrigaUtgifterPerMånad] [money] NULL, [RänteAvdragIProcentPerÅr] [decimal](6, 2) NULL, CONSTRAINT [PK_Bostad] PRIMARY KEY CLUSTERED ( [BostadId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
Scenario
CREATE TABLE [dbo].[Scenario]( [ScenarioId] [int] IDENTITY(1,1) NOT NULL, [ScenarioKod] [varchar](10) NOT NULL, [StartÅr] [int] NULL, [SlutÅr] [int] NULL, [InflationProcentPerÅr] [decimal](6, 3) NULL, [VärdeFörändringProcentPerÅr] [decimal](6, 3) NULL, [NettoInkomstFörändringProcentPerÅr] [decimal](6, 3) NULL, [RänteAvdragProcentPerÅr] [decimal](6, 3) NULL, [RäntaProcentPerÅr] [decimal](6, 3) NULL, [AktieFörändringProcentPerÅr] [decimal](6, 3) NULL, [FonderFörändringProcentPerÅr] [decimal](6, 3) NULL, [SparkontoFörändringProcentPerÅr] [decimal](6, 3) NULL, PRIMARY KEY CLUSTERED ( [ScenarioId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
Vi sätter in lite dummydata för att få två bostadsalternativ med en relativt hög sparkvot i bostadstabellen:
INSERT INTO [MISC].[dbo].[Bostad] ([BostadNamn] ,[TypAvBostad] ,[BostadInköpskostnad] ,[BostadInsats] ,[NettoInkomstPerMånad] ,[HyraEllerAvgiftPerMånad] ,[ÖverlåtelseAvgift] ,[MäklarArvodeIProcentVidFörsäljning] ,[AvdragIProcentVidFörsäljning] ,[UnderhållPerMånad] ,[AmorteringPerMånad] ,[SparandeSparkontoInsats] ,[SparandeMånadssparProcentPerNettoAllt] ,[AktierInsats] ,[AktierMånadssparProcentPerNettoAllt] ,[FonderInsats] ,[FonderMånadssparProcentPerNettoAllt] ,[ElperMånad] ,[FörsäkringperMånad] ,[BredbandperMånad] ,[TvperMånad] ,[MatPerMånad] ,[ÖvrigaUtgifterPerMånad]) VALUES ( 'storgatan 1, 53 kvm',--<BostadNamn, varchar(100),> -- Namnet på bostaden 'Bostadsrätt',--,<TypAvBostad, varchar(20),> -- villa, bostadsrätt, hyresrätt 1800000,--,<BostadInköpskostnad, money,> -- Inköpskostnaden för villa och bostadsrätt i lokal valuta 270000,--,<BostadInsats, money,> -- Insatsen i lokal valuta 18000,--,<NettoInkomstPerMånad, money,> -- Inkomsten efter skatteavdrag (inkl. även andra bidrag netto) 3000,--,<HyraEllerAvgiftPerMånad, money,> -- hyresrätt: månadshyra, bostadrätt: avgift, villa: schablonskatt? eller 0 1000,--,<ÖverlåtelseAvgift, money,> -- kostnad vid inflyttning: hyresrätt: avgifter till förmedlare, bostadsrätt: pant, villa: pantbrev etc 2.5,--,<MäklarArvodeIProcentVidFörsäljning, money,> -- vid brf och hyresrätt 22,--,<AvdragIProcentVidFörsäljning, decimal(6,2),> -- reavinstskatt i % 1500,--,<UnderhållPerMånad, money,> -- underhåll per månad exkl renovering. 0 för hyresrätt, ca 750-2000 för brf, 2000-5000 för villa, något lägre för radhus. 2500,--,<AmorteringPerMånad, money,> -- för brf/villa: amortering på lånet (räknas INTE som kostnad i senare skede, då amortering är ett sorts sparande) 25000,--,<SparandeSparkontoInsats, money,> -- saldo på sparkontot i början av beräkningen, behöver inte användas 60,--,<SparandeMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på sparkonto 10000,--,<AktierInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för aktier), behöver inte användas 40,--,<AktierMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå 0,--,<FonderInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för fonder), behöver inte användas 0,--,<FonderMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå (för fonder), behöver inte användas 300,--,<ElperMånad, money,> -- kostnaden för el per månad 200,--,<FörsäkringperMånad, money,> -- kostnaden för försäkringar per månad relaterade till huset, familjeförsäkring 300,--,<BredbandperMånad, money,> -- kostnaden för bredband per månad (inkluderar även hemtelefoni) 200,--,<TvperMånad, money,> -- kostnaden för tv per månad (inklusive tv-avgift) 1500,--,<MatPerMånad, money,> -- kostnaden för mat per månad 2000--,<ÖvrigaUtgifterPerMånad, money,> -- kostnaden för andra utgifter per månad ) , ( 'villavägen 1, 150 kvm',--<BostadNamn, varchar(100),> -- Namnet på bostaden 'Villa',--,<TypAvBostad, varchar(20),> -- villa, bostadsrätt, hyresrätt 3800000,--,<BostadInköpskostnad, money,> -- Inköpskostnaden för villa och bostadsrätt i lokal valuta 670000,--,<BostadInsats, money,> -- Insatsen i lokal valuta 36000,--,<NettoInkomstPerMånad, money,> -- Inkomsten efter skatteavdrag (inkl. även andra bidrag netto) 500,--,<HyraEllerAvgiftPerMånad, money,> -- hyresrätt: månadshyra, bostadrätt: avgift, villa: schablonskatt? eller 0 100000,--,<ÖverlåtelseAvgift, money,> -- kostnad vid inflyttning: hyresrätt: avgifter till förmedlare, bostadsrätt: pant, villa: pantbrev etc 2.5,--,<MäklarArvodeIProcentVidFörsäljning, money,> -- vid brf och hyresrätt 22,--,<AvdragIProcentVidFörsäljning, decimal(6,2),> -- reavinstskatt i % 4500,--,<UnderhållPerMånad, money,> -- underhåll per månad exkl renovering. 0 för hyresrätt, ca 750-2000 för brf, 2000-5000 för villa, något lägre för radhus. 5000,--,<AmorteringPerMånad, money,> -- för brf/villa: amortering på lånet (räknas INTE som kostnad i senare skede, då amortering är ett sorts sparande) 50000,--,<SparandeSparkontoInsats, money,> -- saldo på sparkontot i början av beräkningen, behöver inte användas 50,--,<SparandeMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på sparkonto 30000,--,<AktierInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för aktier), behöver inte användas 50,--,<AktierMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå 0,--,<FonderInsats, money,> -- saldo på ISK/KF/VP-depå i början av beräkningen (för fonder), behöver inte användas 0,--,<FonderMånadssparProcentPerNettoAllt, money,> -- procent av netto som går in på ISK/KF/VP-depå (för fonder), behöver inte användas 700,--,<ElperMånad, money,> -- kostnaden för el per månad 400,--,<FörsäkringperMånad, money,> -- kostnaden för försäkringar per månad relaterade till huset, familjeförsäkring 600,--,<BredbandperMånad, money,> -- kostnaden för bredband per månad (inkluderar även hemtelefoni) 400,--,<TvperMånad, money,> -- kostnaden för tv per månad (inklusive tv-avgift) 5000,--,<MatPerMånad, money,> -- kostnaden för mat per månad 7000--,<ÖvrigaUtgifterPerMånad, money,> -- kostnaden för andra utgifter per månad ) GO
och lite data i scenario-tabellen:
INSERT INTO [MISC].[dbo].[Scenario] ([ScenarioKod] ,[StartÅr] ,[SlutÅr] ,[InflationProcentPerÅr] ,[VärdeFörändringProcentPerÅr] ,[NettoInkomstFörändringProcentPerÅr] ,[RänteAvdragProcentPerÅr] ,[RäntaProcentPerÅr] ,[AktieFörändringProcentPerÅr] ,[FonderFörändringProcentPerÅr] ,[SparkontoFörändringProcentPerÅr]) VALUES ( 'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario 0, --,<StartÅr, int,> -- startår för raden 3, --,<SlutÅr, int,> -- slutår för raden 1, --,<InflationProcentPerÅr, decimal(6,3),> 4, --,<VärdeFörändringProcentPerÅr, decimal(6,3),> 2, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),> 30, --,<RänteAvdragProcentPerÅr, decimal(6,3),> 2.5, --,<RäntaProcentPerÅr, decimal(6,3),> 5, --,<AktieFörändringProcentPerÅr, decimal(6,3),> 5, --,<FonderFörändringProcentPerÅr, decimal(6,3),> 1--,<SparkontoFörändringProcentPerÅr, decimal(6,3),> ), ( 'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario 4, --,<StartÅr, int,> -- startår för raden 6, --,<SlutÅr, int,> -- slutår för raden 3, --,<InflationProcentPerÅr, decimal(6,3),> -3, --,<VärdeFörändringProcentPerÅr, decimal(6,3),> 4, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),> 20, --,<RänteAvdragProcentPerÅr, decimal(6,3),> 5.5, --,<RäntaProcentPerÅr, decimal(6,3),> -4, --,<AktieFörändringProcentPerÅr, decimal(6,3),> -3, --,<FonderFörändringProcentPerÅr, decimal(6,3),> 5--,<SparkontoFörändringProcentPerÅr, decimal(6,3),> ), ( 'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario 7, --,<StartÅr, int,> -- startår för raden 12, --,<SlutÅr, int,> -- slutår för raden 4, --,<InflationProcentPerÅr, decimal(6,3),> 1, --,<VärdeFörändringProcentPerÅr, decimal(6,3),> 5, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),> 10, --,<RänteAvdragProcentPerÅr, decimal(6,3),> 6.5, --,<RäntaProcentPerÅr, decimal(6,3),> 7, --,<AktieFörändringProcentPerÅr, decimal(6,3),> 6, --,<FonderFörändringProcentPerÅr, decimal(6,3),> 5--,<SparkontoFörändringProcentPerÅr, decimal(6,3),> ), ( 'Scenario1', --<ScenarioKod, varchar(10),> -- Namn på scenario 13, --,<StartÅr, int,> -- startår för raden 20, --,<SlutÅr, int,> -- slutår för raden 2.5, --,<InflationProcentPerÅr, decimal(6,3),> 3, --,<VärdeFörändringProcentPerÅr, decimal(6,3),> 4, --,<NettoInkomstFörändringProcentPerÅr, decimal(6,3),> 0, --,<RänteAvdragProcentPerÅr, decimal(6,3),> 5.5, --,<RäntaProcentPerÅr, decimal(6,3),> 7, --,<AktieFörändringProcentPerÅr, decimal(6,3),> 7, --,<FonderFörändringProcentPerÅr, decimal(6,3),> 3--,<SparkontoFörändringProcentPerÅr, decimal(6,3),> ) GO
Stored procedure
-- ============================================= -- Author: Robin Langell -- Create date: 2014-06-08 -- Description: Räknar ut bostadskostnader -- ============================================= CREATE PROCEDURE [dbo].[usp_BostadsKostnad] @BostadId1 int = 1,-- första bostadid, @BostadId2 int = 2,-- andra bostadid, @PeriodAntalÅr int = 15, @PeriodStart date = '2014-08-01', @InkluderaBostadFörsäljningKostnaderOchVinsterFlagga int = 1, @ScenarioKod varchar(10) = 'A' AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Pseudokod: -- hämta all info från tabellen. (id) SELECT RadNr = ROW_NUMBER() OVER (ORDER BY (SELECT NULL) ) ,[BostadId] ,[BostadNamn] ,[TypAvBostad] ,[BostadInköpskostnad] ,[BostadInsats] ,[NettoInkomstPerMånad] ,[HyraEllerAvgiftPerMånad] ,[ÖverlåtelseAvgift] ,[MäklarArvodeIProcentVidFörsäljning] ,[AvdragIProcentVidFörsäljning] ,[UnderhållPerMånad] ,[AmorteringPerMånad] ,[SparandeSparkontoInsats] ,[SparandeMånadssparProcentPerNettoAllt] ,[AktierInsats] ,[AktierMånadssparProcentPerNettoAllt] ,[FonderInsats] ,[FonderMånadssparProcentPerNettoAllt] ,[ElperMånad] ,[FörsäkringperMånad] ,[BredbandperMånad] ,[TvperMånad] ,[MatPerMånad] ,[ÖvrigaUtgifterPerMånad] INTO #Bostad_grunddata FROM dbo.Bostad GD WHERE BostadId IN (@BostadId1,@BostadId2) -- skapa tabell med månader från startdatum ;WITH L0 AS(SELECT 1 AS C UNION ALL SELECT 1 AS O), -- 2 rows L1 AS(SELECT 1 AS C FROM L0 AS A CROSS JOIN L0 AS B), -- 4 rows L2 AS(SELECT 1 AS C FROM L1 AS A CROSS JOIN L1 AS B), -- 16 rows L3 AS(SELECT 1 AS C FROM L2 AS A CROSS JOIN L2 AS B), -- 256 rows L4 AS(SELECT 1 AS C FROM L3 AS A CROSS JOIN L3 AS B), -- 65,536 rows L5 AS(SELECT 1 AS C FROM L4 AS A CROSS JOIN L4 AS B), -- 4,294,967,296 rows Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS N FROM L5) SELECT TOP (12*@PeriodAntalÅr) MånadsNr = N-1, Månad = DATEADD(MONTH, N-1, @PeriodStart), År = CAST( FLOOR( (N-1) / 12.00 ) AS INT), S.InflationProcentPerÅr, S.NettoInkomstFörändringProcentPerÅr, S.RäntaProcentPerÅr, S.RänteAvdragProcentPerÅr, S.VärdeFörändringProcentPerÅr, S.AktieFörändringProcentPerÅr, S.FonderFörändringProcentPerÅr, S.SparkontoFörändringProcentPerÅr INTO #Månader FROM Nums N LEFT JOIN dbo.Scenario S ON CAST( FLOOR( (N.N-1) / 12.00 ) AS INT) BETWEEN S.StartÅr AND S.SlutÅr WHERE S.ScenarioKod = @ScenarioKod DECLARE @bostad_i int = 1, @bostad_i_max int = (SELECT MAX(RadNr) FROM #Bostad_grunddata ) DECLARE @current_BostadId as DECIMAL(38,18) ,@current_BostadNamn as varchar(100) ,@current_TypAvBostad as varchar(50) ,@current_BostadInköpskostnad as DECIMAL(38,18) ,@current_BostadInsats as DECIMAL(38,18) ,@current_NettoInkomstPerMånad as DECIMAL(38,18) ,@current_HyraEllerAvgiftPerMånad as DECIMAL(38,18) ,@current_ÖverlåtelseAvgift as DECIMAL(38,18) ,@current_MäklarArvodeIProcentVidFörsäljning as DECIMAL(38,18) ,@current_AvdragIProcentVidFörsäljning as DECIMAL(38,18) ,@current_UnderhållPerMånad as DECIMAL(38,18) ,@current_AmorteringPerMånad as DECIMAL(38,18) ,@current_SparandeSparkontoInsats as DECIMAL(38,18) ,@current_SparandeMånadssparProcentPerNettoAllt as DECIMAL(38,18) ,@current_SparandeProcentPerÅrUtv as DECIMAL(38,18) ,@current_AktierInsats as DECIMAL(38,18) ,@current_AktierMånadssparProcentPerNettoAllt as DECIMAL(38,18) ,@current_AktierProcentPerÅrUtv as DECIMAL(38,18) ,@current_FonderInsats as DECIMAL(38,18) ,@current_FonderMånadssparProcentPerNettoAllt as DECIMAL(38,18) ,@current_FonderProcentPerÅrUtv as DECIMAL(38,18) ,@current_ElperMånad as DECIMAL(38,18) ,@current_FörsäkringperMånad as DECIMAL(38,18) ,@current_BredbandperMånad as DECIMAL(38,18) ,@current_TvperMånad as DECIMAL(38,18) ,@current_MatPerMånad as DECIMAL(38,18) ,@current_ÖvrigaUtgifterPerMånad as DECIMAL(38,18) ,@current_Lån as DECIMAL(38,18) = -1 ,@current_BelåningsgradIProcent as DECIMAL(20,17) = NULL ,@current_BostadsVärde as DECIMAL(38,18) = NULL ,@current_RänteKostnad as DECIMAL(38,18) = NULL ,@current_RänteProcent as DECIMAL(38,18) = NULL ,@current_NettoInkomstFörändringProcentPerÅr AS DECIMAL(38,18) ,@current_RänteAvdragProcentPerÅr as DECIMAL(38,18) ,@current_värdeFörändringProcentPerÅr as DECIMAL(38,18) ,@current_InflationIProcentPerÅr as DECIMAL(38,18) CREATE TABLE #BoOchSparBudget ( ID INT, ScenarioKod varchar(10), Datum date, Lägenhetsnamn varchar(100), TypAvBostad varchar(50), Månad_Inkomst money, -- Månadsrelaterad info: Månad_TotalKostnad money, Månad_Räntekostnad money, Månad_AktuellSkuld money, Månad_Bostadsvärde money, Månad_Amortering money, Månad_Belåningsgrad decimal(12,8), Månad_ÖvrigaUtgifterUnderMånad money, Månad_SparkvotAvNettoInkomst money, -- Ack: Ackumulerad_Kostnad money, Ackumulerad_RänteKostnad money, Ackumulerad_Amortering money, Ackumulerad_AktieKonto money, Ackumulerad_FonderKonto money, Ackumulerad_SparKonto money, NettoSkuldsättning money, FörsäljningsKostnader money ) CREATE TABLE #Månadskostnader ( current_Månad date, current_InflationIProcentPerÅr decimal(38,18), current_Lån decimal(38,18), current_BostadsVärde decimal(38,18), current_BelåningsgradIProcent decimal(38,18), current_RänteProcent decimal(38,18), current_RänteKostnad decimal(38,18), current_ÖvrigKostnad decimal(38,18) ) -- loopa per bostadId WHILE (@bostad_i <= @bostad_i_max ) BEGIN SELECT @current_BostadId = BostadId ,@current_BostadNamn = BostadNamn ,@current_TypAvBostad = TypAvBostad ,@current_BostadInköpskostnad = BostadInköpskostnad ,@current_BostadInsats = BostadInsats ,@current_NettoInkomstPerMånad = NettoInkomstPerMånad ,@current_HyraEllerAvgiftPerMånad = HyraEllerAvgiftPerMånad ,@current_ÖverlåtelseAvgift = ÖverlåtelseAvgift ,@current_MäklarArvodeIProcentVidFörsäljning = MäklarArvodeIProcentVidFörsäljning ,@current_AvdragIProcentVidFörsäljning = AvdragIProcentVidFörsäljning ,@current_UnderhållPerMånad = UnderhållPerMånad ,@current_AmorteringPerMånad = AmorteringPerMånad ,@current_SparandeSparkontoInsats = SparandeSparkontoInsats ,@current_SparandeMånadssparProcentPerNettoAllt = SparandeMånadssparProcentPerNettoAllt ,@current_AktierInsats = AktierInsats ,@current_AktierMånadssparProcentPerNettoAllt = AktierMånadssparProcentPerNettoAllt ,@current_FonderInsats = FonderInsats ,@current_FonderMånadssparProcentPerNettoAllt = FonderMånadssparProcentPerNettoAllt ,@current_ElperMånad = ElperMånad ,@current_FörsäkringperMånad = FörsäkringperMånad ,@current_BredbandperMånad = BredbandperMånad ,@current_TvperMånad = TvperMånad ,@current_MatPerMånad = MatPerMånad ,@current_ÖvrigaUtgifterPerMånad = ÖvrigaUtgifterPerMånad ,@current_BostadsVärde = @current_BostadInköpskostnad FROM #Bostad_grunddata WHERE RadNr = @bostad_i -- loopa per månad -- ackumulera -- summera DECLARE @månad_i int = 1 ,@månad_i_max int = (SELECT MAX(MånadsNr) FROM #Månader ) ,@current_Månad date = (SELECT MIN(Månad) FROM #Månader ) -- börjar alltid på år 0: ,@current_År int = 0 ,@årFörändringFlagga bit = 0 ,@Current_NettoSparande money = 0 ,@Current_Ackumulerad_Kostnad money = 0 ,@Current_Ackumulerad_RänteKostnad money = 0 ,@Current_Ackumulerad_Amortering money = 0 ,@Current_Försäljningskostnad money = 0 WHILE (@månad_i <= @månad_i_max) BEGIN -- hämta månader, kolla om år har ändrats: SELECT @current_Månad = Månad, @current_År = År, @årFörändringFlagga = CASE WHEN @current_År = År THEN 1 ELSE 1 END, @current_InflationIProcentPerÅr = M.InflationProcentPerÅr, @current_NettoInkomstFörändringProcentPerÅr = M.NettoInkomstFörändringProcentPerÅr, @current_RänteProcent = RäntaProcentPerÅr, @current_RänteAvdragProcentPerÅr = RänteAvdragProcentPerÅr, @current_värdeförändringProcentPerÅr = M.VärdeFörändringProcentPerÅr, @current_AktierProcentPerÅrUtv = M.AktieFörändringProcentPerÅr, @current_FonderProcentPerÅrUtv = M.FonderFörändringProcentPerÅr, @current_SparandeProcentPerÅrUtv = M.SparkontoFörändringProcentPerÅr FROM #Månader M WHERE @månad_i = MånadsNr SELECT -- räkna ut nettolönen (ny varje år): @current_NettoInkomstPerMånad = CASE WHEN @månad_i % 12 = 1 THEN @current_NettoInkomstPerMånad * (1 + (@current_NettoInkomstFörändringProcentPerÅr/100.00) ) ELSE @current_NettoInkomstPerMånad END, -- Följer inflationen: @current_HyraEllerAvgiftPerMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ) , @current_ElperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), @current_FörsäkringperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), @current_BredbandperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), @current_TvperMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), @current_MatPerMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ), @current_ÖvrigaUtgifterPerMånad *= (1 + ( (@current_InflationIProcentPerÅr/12.00) /100.00) ) /* **************************************************** */ -- Övriga månadsutgifter: /* **************************************************** */ SELECT @Current_NettoSparande = @current_NettoInkomstPerMånad - ( @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad ) - CASE WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift ELSE 0 END SELECT @Current_Ackumulerad_Kostnad += ( @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad ) + CASE WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift ELSE 0 END /* **************************************************** */ -- Sparande: /* **************************************************** */ SELECT @current_AktierInsats = ( @current_AktierInsats + ( (@current_AktierMånadssparProcentPerNettoAllt / 100.00) * @Current_NettoSparande ) ) * (1 + ( (@current_AktierProcentPerÅrUtv/100.00) / 12.00) ), @current_FonderInsats = ( @current_FonderInsats + ( (@current_FonderMånadssparProcentPerNettoAllt / 100.00) * @Current_NettoSparande ) ) * (1 + ( (@current_FonderProcentPerÅrUtv/100.00) / 12.00) ), @current_SparandeSparkontoInsats = ( @current_SparandeSparkontoInsats + ( (@current_SparandeMånadssparProcentPerNettoAllt / 100.00) * @Current_NettoSparande ) ) * (1 + ( (@current_SparandeProcentPerÅrUtv/100.00) / 12.00) ) -- Vid hyresrätt: IF(@current_TypAvBostad = 'Hyresrätt') BEGIN INSERT INTO #BoOchSparBudget ( ID, Datum , Lägenhetsnamn , TypAvBostad , -- Månadsrelaterad info: Månad_TotalKostnad , Månad_Räntekostnad , Månad_AktuellSkuld , Månad_Bostadsvärde , Månad_Amortering , Månad_Belåningsgrad , Månad_ÖvrigaUtgifterUnderMånad , Månad_SparkvotAvNettoInkomst , -- Ack: Ackumulerad_Kostnad , Ackumulerad_RänteKostnad , Ackumulerad_Amortering , Ackumulerad_AktieKonto , Ackumulerad_FonderKonto , Ackumulerad_SparKonto , NettoSkuldsättning , Månad_Inkomst, ScenarioKod, FörsäljningsKostnader ) SELECT @bostad_i, @current_Månad, @current_BostadNamn, @current_TypAvBostad, Månad_TotalKostnad = @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad + CASE WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift ELSE 0 END , Månad_Räntekostnad = NULL, Månad_AktuellSkuld = NULL, Månad_Bostadsvärde = NULL, Månad_amortering = NULL, Månad_belåningsgrad = NULL, Månad_ÖvrigaUtgifterUnderMånad = @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad, Månad_SparkvotAvNettoInkomst = @Current_NettoSparande / @current_NettoInkomstPerMånad, -- Ack: Ackumulerad_kostnad = @Current_Ackumulerad_Kostnad, Ackumulerad_RänteKostnad = NULL, Ackumulerad_Amortering = NULL, Ackumulerad_AktieKonto = @current_AktierInsats, Ackumulerad_FonderKonto = @current_FonderInsats, Ackumulerad_SparKonto = @current_SparandeSparkontoInsats, NettoSkuld = ISNULL(@current_Lån, 0) - (@current_AktierInsats + @current_FonderInsats + @current_SparandeSparkontoInsats), NettoInkomstPerMånad = @current_NettoInkomstPerMånad, @ScenarioKod, FörsäljningsKostnader = 0 END ELSE IF (@current_TypAvBostad IN ( 'Bostadsrätt', 'Villa', 'Radhus') ) BEGIN -- /* **************************************************** */ -- -- Bostadsrelaterade månadsutgifter: -- /* **************************************************** */ SELECT -- räkna ut skulden efter amortering: @current_Lån = CASE WHEN @månad_i = 1 AND @current_BostadInköpskostnad > 0 THEN @current_BostadInköpskostnad - @current_BostadInsats WHEN @current_Lån >= 0 THEN @current_Lån - @current_AmorteringPerMånad END SELECT -- räkna ut bostadsvärdet: @current_BostadsVärde *= (1+((@current_värdeförändringProcentPerÅr/100.00)/12.00)) --@current_BostadsVärde = @current_BostadsVärde SELECT -- räkna ut belåningsgraden: @current_BelåningsgradIProcent = @current_Lån / @current_BostadsVärde SELECT -- räkna ut månadsräntekostnaden på lånet: @current_RänteKostnad = @current_Lån * ((@current_RänteProcent/100.00)/12.00) * (1-(@current_RänteAvdragProcentPerÅr/100.00) ) -- Ackumulerade värden: SELECT @Current_Ackumulerad_RänteKostnad = ISNULL(@Current_Ackumulerad_RänteKostnad, 0) + @current_RänteKostnad, @Current_Ackumulerad_Kostnad += ( @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad ) + ISNULL(@current_RänteKostnad, 0 ) + CASE WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift ELSE 0 END , @Current_Ackumulerad_Amortering += @current_AmorteringPerMånad, @Current_Försäljningskostnad = CASE WHEN @månad_i = @månad_i_max AND @InkluderaBostadFörsäljningKostnaderOchVinsterFlagga = 1 THEN -- om vinst vid försäljning: CASE WHEN @current_BostadsVärde > @current_BostadInköpskostnad THEN (@current_BostadsVärde - @current_BostadInköpskostnad) * (@current_AvdragIProcentVidFörsäljning/100.00) ELSE 0 END + @current_BostadsVärde * (@current_MäklarArvodeIProcentVidFörsäljning/100.00) ELSE 0 END /* ********************************** */ -- #BoOchSparBudget /* ********************************** */ INSERT INTO #BoOchSparBudget ( ID, Datum , Lägenhetsnamn , TypAvBostad , -- Månadsrelaterad info: Månad_TotalKostnad , Månad_Räntekostnad , Månad_AktuellSkuld , Månad_Bostadsvärde , Månad_Amortering , Månad_Belåningsgrad , Månad_ÖvrigaUtgifterUnderMånad , Månad_SparkvotAvNettoInkomst , -- Ack: Ackumulerad_Kostnad , Ackumulerad_RänteKostnad , Ackumulerad_Amortering , Ackumulerad_AktieKonto , Ackumulerad_FonderKonto , Ackumulerad_SparKonto , NettoSkuldsättning , Månad_Inkomst, ScenarioKod, FörsäljningsKostnader ) SELECT @bostad_i, @current_Månad, @current_BostadNamn, @current_TypAvBostad, Månad_TotalKostnad = @current_HyraEllerAvgiftPerMånad + @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad + ISNULL(@current_RänteKostnad, 0) + CASE WHEN @månad_i = 1 THEN @current_ÖverlåtelseAvgift ELSE 0 END + @Current_Försäljningskostnad , Månad_Räntekostnad = @current_RänteKostnad, Månad_AktuellSkuld = @current_Lån, Månad_Bostadsvärde = @current_BostadsVärde, Månad_amortering = @current_AmorteringPerMånad, Månad_belåningsgrad = @current_BelåningsgradIProcent, Månad_ÖvrigaUtgifterUnderMånad = @current_ElperMånad + @current_FörsäkringperMånad + @current_BredbandperMånad + @current_TvperMånad + @current_MatPerMånad + @current_ÖvrigaUtgifterPerMånad, Månad_SparkvotAvNettoInkomst = @Current_NettoSparande / @current_NettoInkomstPerMånad, -- Ack: Ackumulerad_kostnad = @Current_Ackumulerad_Kostnad + @Current_Försäljningskostnad, Ackumulerad_RänteKostnad = @Current_Ackumulerad_RänteKostnad, Ackumulerad_Amortering = @Current_Ackumulerad_Amortering, Ackumulerad_AktieKonto = @current_AktierInsats, Ackumulerad_FonderKonto = @current_FonderInsats, Ackumulerad_SparKonto = @current_SparandeSparkontoInsats, NettoSkuld = ISNULL(@current_Lån, 0) - (@current_AktierInsats + @current_FonderInsats + @current_SparandeSparkontoInsats) -- Räkna med värdet på bostaden efter lånet räknats bort: - (@current_BostadsVärde-@current_Lån) + @Current_Försäljningskostnad , NettoInkomstPerMånad = @current_NettoInkomstPerMånad, @ScenarioKod, FörsäljningsKostnader = @Current_Försäljningskostnad END SET @månad_i = (@månad_i + 1) SET @årFörändringFlagga = 0 END SET @bostad_i = (@bostad_i + 1) -- 0 på den bostad vi nyss har kört igenom: SELECT @current_BostadInköpskostnad = NULL ,@current_BostadInsats = NULL ,@current_NettoInkomstPerMånad = NULL ,@current_InflationIProcentPerÅr = NULL ,@current_HyraEllerAvgiftPerMånad = NULL ,@current_ÖverlåtelseAvgift = NULL ,@current_MäklarArvodeIProcentVidFörsäljning = NULL ,@current_AvdragIProcentVidFörsäljning = NULL ,@current_UnderhållPerMånad = NULL ,@current_AmorteringPerMånad = NULL ,@current_SparandeSparkontoInsats = NULL ,@current_SparandeMånadssparProcentPerNettoAllt = NULL ,@current_SparandeProcentPerÅrUtv = NULL ,@current_AktierInsats = NULL ,@current_AktierMånadssparProcentPerNettoAllt = NULL ,@current_AktierProcentPerÅrUtv = NULL ,@current_FonderInsats = NULL ,@current_FonderMånadssparProcentPerNettoAllt = NULL ,@current_FonderProcentPerÅrUtv = NULL ,@current_ElperMånad = NULL ,@current_FörsäkringperMånad = NULL ,@current_BredbandperMånad = NULL ,@current_TvperMånad = NULL ,@current_MatPerMånad = NULL ,@current_ÖvrigaUtgifterPerMånad = NULL ,@current_Lån = NULL ,@current_InflationIProcentPerÅr = NULL ,@current_BostadsVärde = NULL ,@current_BelåningsgradIProcent = NULL ,@current_RänteProcent = NULL ,@current_RänteKostnad = NULL ,@Current_NettoSparande = 0 ,@Current_Ackumulerad_Kostnad = 0 ,@Current_Ackumulerad_RänteKostnad = 0 ,@Current_Ackumulerad_Amortering = 0 ,@current_Lån = 0 ,@Current_Försäljningskostnad = 0 END -- resultat SELECT Alt1.ScenarioKod, Alt1.Datum, Alt1_Månad_Inkomst = Alt1.Månad_Inkomst, Alt2_Månad_Inkomst = Alt2.Månad_Inkomst, Alt1_Lägenhetsnamn = Alt1.Lägenhetsnamn, Alt1_TypAvBostad = Alt1.TypAvBostad, Alt2_Lägenhetsnamn = Alt2.Lägenhetsnamn, Alt2_TypAvBostad = Alt2.TypAvBostad, Alt1_Månad_Bostadsvärde = Alt1.Månad_Bostadsvärde, Alt2_Månad_Bostadsvärde = Alt2.Månad_Bostadsvärde, Alt1_Månad_TotalKostnad = Alt1.Månad_TotalKostnad, Alt2_Månad_TotalKostnad = Alt2.Månad_TotalKostnad, Alt1_Månad_AktuellSkuld = Alt1.Månad_AktuellSkuld, Alt2_Månad_AktuellSkuld = Alt2.Månad_AktuellSkuld, Alt1_Månad_Amortering = Alt1.Månad_Amortering, Alt2_Månad_Amortering = Alt2.Månad_Amortering, Alt1_Månad_Räntekostnad = Alt1.Månad_Räntekostnad, Alt2_Månad_Räntekostnad = Alt2.Månad_Räntekostnad, Alt1_Månad_ÖvrigaUtgifterUnderMånad = Alt1.Månad_ÖvrigaUtgifterUnderMånad, Alt2_Månad_ÖvrigaUtgifterUnderMånad = Alt2.Månad_ÖvrigaUtgifterUnderMånad, Alt1_Månad_Belåningsgrad = Alt1.Månad_Belåningsgrad, Alt2_Månad_Belåningsgrad = Alt2.Månad_Belåningsgrad, Alt1_månad_sparkvotavNettoInkomst = Alt1.månad_sparkvotavNettoInkomst, Alt2_månad_sparkvotavNettoInkomst = Alt2.månad_sparkvotavNettoInkomst, Alt1_NettoSkuldsättning = Alt1.NettoSkuldsättning, Alt2_NettoSkuldsättning = Alt2.NettoSkuldsättning, Alt1_FörsäljningsKostnader = Alt1.FörsäljningsKostnader, Alt2_FörsäljningsKostnader = Alt2.FörsäljningsKostnader, -- ACKUMULERADE VÄRDEN: Alt1_Ackumulerad_Kostnad = Alt1.Ackumulerad_Kostnad, Alt2_ackumulerad_kostnad = Alt2.ackumulerad_kostnad, Alt1_Ackumulerad_RänteKostnad = Alt1.Ackumulerad_RänteKostnad, Alt2_Ackumulerad_RänteKostnad = Alt2.Ackumulerad_RänteKostnad, alt1_Ackumulerad_Amortering = alt1.Ackumulerad_Amortering, Alt2_Ackumulerad_Amortering = Alt2.Ackumulerad_Amortering, Alt1_Ackumulerad_AktieKonto = Alt1.Ackumulerad_AktieKonto, Alt2_Ackumulerad_AktieKonto = Alt2.Ackumulerad_AktieKonto, Alt1_Ackumulerad_FonderKonto = Alt1.Ackumulerad_FonderKonto, Alt2_Ackumulerad_FonderKonto = Alt2.Ackumulerad_FonderKonto, Alt1_Ackumulerad_SparKonto = Alt1.Ackumulerad_SparKonto, Alt2_Ackumulerad_SparKonto = Alt2.Ackumulerad_SparKonto FROM #BoOchSparBudget Alt1 JOIN #BoOchSparBudget Alt2 ON Alt1.ID + 1 = Alt2.ID AND Alt1.Datum = Alt2.Datum END GO
För att testa koden så kör du exempelvis detta anrop:
EXEC [dbo].[usp_BostadsKostnad] @BostadId1 = 1,-- första bostadid, @BostadId2 = 2,-- andra bostadid, @PeriodAntalÅr = 15, -- antal år @PeriodStart = '2014-08-01', -- när startar jämförelsen @InkluderaBostadFörsäljningKostnaderOchVinsterFlagga = 1, -- inkludera mäklararvode och reavinstskatt som kostnader (vilket det är!) @ScenarioKod = 'Scenario1' -- vilket framtidsscenario ska användas?
Vi får då ett resultat där vi kan utläsa bostadsvärde, nettokapital, kostnader, amorteringar och sparande. Det finns såklart många aber med denna kod. Just nu finns exempelvis ingen förmögenhetsskatt eller någon ordentlig fastighetsskatt. Amorteringen är rak, vilket inte alla kör med. Man kan heller inte välja amorteringsfritt över en övergående period.