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)