DECLARE @TempTable TABLE ( Amount MONEY, InsurType VARCHAR(100), MonthNumber INT, PostDate DATETIME, DaysInMonth INT ) INSERT INTO @TempTable VALUES (2019317, 'Commercial Auto', 1, '2018-01-01 00:00:00.000', 31), (3757832, 'Commercial Auto', 2, '2018-01-01 00:00:00.000', 28), (5010746, 'Commercial Auto', 3, '2018-01-01 00:00:00.000', 31), (4461429.66, 'Commercial Auto', 4, '2018-01-01 00:00:00.000', 30), (4049404.44, 'Commercial Auto', 5, '2018-01-01 00:00:00.000', 31) SELECT * FROM @TempTable Result looks like that:Is it possible to break down the amount by each day of the month for all 5 months?For example the Amount for MonthNumber 1 is = $2,019,317 / 31 = $65,139 per day. The output should look like this:
6 Réponses :
C'est assez facile vraiment. Il suffit de rejoindre une table des chiffres sur le nombre égal ou inférieur au nombre de jours dans le mois, et le montant n'est que le total divisé par le nombre de jours. P>
juste une jointure intérieure avec (valeurs (1), ..., (31)) code>. Vous ne pouvez pas avoir plus de 31 jours par mois, il est donc plus facile de les taper.
Aussi une option. Je me demande comment cela fonctionne par rapport à une table "chiffres" indexée. Probablement assez proche puisqu'un index n'a probablement pas ajouté que beaucoup à une table de chiffres.
avec une table de contact comme une option supplémentaire pour le constructeur de table.
create table #TempTable ( Amount Money, InsurType varchar(100), MonthNumber int, PostDate datetime, DaysInMonth int ) INSERT INTO #TempTable values (2019317,'Commercial Auto', 1, '2018-01-01 00:00:00.000',31 ), (3757832,'Commercial Auto', 2, '2018-01-01 00:00:00.000',28 ), (5010746,'Commercial Auto', 3, '2018-01-01 00:00:00.000',31 ), (4461429.66,'Commercial Auto', 4, '2018-01-01 00:00:00.000',30 ), (4049404.44,'Commercial Auto', 5, '2018-01-01 00:00:00.000',31 ) ;WITH E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), E2(N) AS (SELECT 1 FROM E1 a, E1 b), cteTally(N) AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2) select * from #TempTable t inner join cteTally on cteTally.N <= t.DaysInMonth order by Amount, N drop table #TempTable
Il existe une table système de valeurs de numéro statique à utiliser. Jouant cette réponse dans le mélange, choisissez votre poison.
select number from master..spt_values d where d.type = 'p' and d.number between 1 and 31 select Amount/cast(DaysInMonth as money) DailyAmt, InsurType, MonthNumber, d.number Day from @TempTable t join master..spt_values d on d.number <= t.DaysInMonth and d.number between 1 and 31
Je me demande pourquoi vous stockez le numéro de mois et les jours dans le mois? Vous pouvez déterminer suffisamment facile à l'aide de SQL:
DECLARE @Nums TABLE(num int) ;WITH nums AS (SELECT 1 AS value UNION ALL SELECT value + 1 AS value FROM nums WHERE nums.value <= 31) insert @Nums SELECT * FROM nums DECLARE @TempTable TABLE ( Amount MONEY, InsurType VARCHAR(100), PostDate DATETIME ) INSERT INTO @TempTable VALUES (2019317, 'Commercial Auto A', '2018-01-01 00:00:00.000'), (3757832, 'Commercial Auto B', '2018-02-01 00:00:00.000'), (5010746, 'Commercial Auto C', '2018-03-01 00:00:00.000'), (4461429.66, 'Commercial Auto D', '2018-04-01 00:00:00.000'), (4049404.44, 'Commercial Auto E', '2018-05-01 00:00:00.000') SELECT (Amount / DAY(EOMONTH(PostDate))) as DailyAmount, InsurType, datepart(month, PostDate) as TheMonth, n.num as TheDay FROM @TempTable tt JOIN @Nums n ON n.num <= DAY(EOMONTH(PostDate)) ORDER BY datepart(month, PostDate)