我有一个看起来像这样的表:
在查询中,我需要找到两个时间段(行)上发生的最大导入值,其中值大于定义的阈值并应用速率。如果它发生超过两个时间段,将使用不同的速率
WITH CTE AS (
SELECT LogTable.[LocalTimestamp] as thetime,LogTable.[SystemImport] as import, LogTable.[Id] - ROW_NUMBER() OVER (ORDER BY LogTable.[Id]) AS grp
FROM {System_KWLogRaw} LogTable
WHERE LogTable.[SystemImport] between @DemandThreshold and @In1 and
DATEPART(year,@inDate) = DATEPART(year, LogTable.[LocalTimestamp]) and
DATEPART(month,@inDate) = DATEPART(month, LogTable.[LocalTimestamp]) and
DATEPART(day,@inDate) = DATEPART(day, LogTable.[LocalTimestamp])
),
counted AS (
SELECT *, COUNT(*) OVER (PARTITION BY grp) AS cnt
FROM CTE
)
SELECT MAX(counted.import) as again1
FROM counted
WHERE cnt > 3 and counted.import < (SELECT MAX(counted.import) FROM counted)
Ids 2和3>阈值,因此查询应返回那些(2500,1900)= 1900减去阈值(1000)= 900的MIN值。应用率Rate1 * 900 = 9000
如果我们将Id 4的值更改为1200,则MIN值将为1200.减去阈值= 200. 200 * Rate2 = 4000
反馈后更新。我的挑战似乎是我没有抓住第二高的价值。以下是数据集的示例: Dataset example
我添加了另一个var来缩小列表以测试间隙和岛屿部分。这是一个较小的子集: Subset
以下是代码:
{{1}}
这将返回3555.53而不是3543.2,这是第二高的值
答案 0 :(得分:0)
这将满足您的要求:
with x as (
select
t1.Id,
t1.DateTime,
t1.Import,
t1.Export,
t1.Total,
count(t2.Import) over (partition by 1) as [QualifyingImports],
min(t2.Import) over (partition by 1) as [MinQualifyingImport]
from
myTable t1
left join myTable t2 on t2.Import > 1000 and t2.Id = t1.Id
where
t1.DateTime >= '2016-01-13'
and t1.DateTime < dateadd(d, 1,'2016-01-13')
)
select
x.Id,
x.DateTime,
x.Import,
x.Export,
x.Total,
case when x.[QualifyingImports] > 2 then (x.MinQualifyingImport - 1000) * 200 else (x.MinQualifyingImport - 1000) * 100 end as [Rate]
from x
我已经整理了一个Fiddle,因此你可以为Id#4使用不同的值。
我真的想把阈值和句点之类的值设置为@variables
,但它似乎不支持CTE,所以我只需要对它们进行硬编码。
修改强>
原来CTE太过分了,你可以把它缩小到这个并使用@variables
,耶!
declare @period smalldatetime = '2016-01-13'
declare @threshold float = 1000
declare @rate1 float = 100
declare @rate2 float = 200
select
t1.Id,
t1.DateTime,
t1.Import,
t1.Export,
t1.Total,
case
when count(t2.Import) over (partition by 1) > 2 then (min(t2.Import) over (partition by 1) - @threshold) * @rate2
else (min(t2.Import) over (partition by 1) - @threshold) * @rate1
end as [Rate]
from
myTable t1
left join myTable t2 on t2.Import > @threshold and t2.Id = t1.Id
where
t1.DateTime >= @period
and t1.DateTime < dateadd(d, 1, @period)