如果一天的运行速度> 0,则其状态为true。
如果特定日期没有数据,则推断最后一个状态代码(另一个
表中的列)值记录,如果该值为零,则将运行状态标记为true。对于非零标记状态的代码,其状态为false。
请参阅下表
Day Run speed Statuscode Status
---------------------------------------
1-Jan-14 55 0 TRUE
2-Jan-14 60 0 TRUE
3-Jan-14 58 0 TRUE
4-Jan-14 61 0 TRUE
5-Jan-14 57 0 TRUE
6-Jan-14 56 0 TRUE
7-Jan-14 60 0 TRUE
8-Jan-14 TRUE
9-Jan-14 TRUE
10-Jan-14 55 0 TRUE
11-Jan-14 56 0 TRUE
12-Jan-14 60 0 TRUE
13-Jan-14 0 20 FALSE
(示例8-jan-14 / 9-jan-14没有值,但是由于上次记录的日期是7,所以这两个日期的状态也为真)
答案 0 :(得分:0)
CASE
语句将为您解决此问题。 OUTER APPLY
将解决第二个要求。
APPLY
,CROSS APPLY
和OUTER APPLY
是最容易理解和使用不足的迭代器。但是,一旦您掌握了它们的功能并理解了用例,它们就会成为您工具箱中的致命武器。它们在TOP(n) [by some logic]
情况下特别有用,在这种情况下,内置函数无法满足您的要求。
请注意使用
BIT
来表示布尔值TRUE/FALSE
SELECT Day
, RunningSpeed
, PreviousRunningSpeed
, CASE
WHEN RunningSpeed IS NULL AND PreviousRunningSpeed > 0 THEN 1
WHEN RunningSpeed > 0 THEN 1
ELSE 0
END AS Status
FROM (SELECT Day
, RunningSpeed
, d.RunningSpeed AS PreviousRunningSpeed
FROM tbl AS t1
OUTER APPLY (SELECT TOP(1)
RunningSpeed
FROM tbl AS t2
WHERE RunningSpeed IS NOT NULL
AND t2.Day < t1.Day
ORDER BY Day ASC)) AS d
答案 1 :(得分:0)
为此,您真正想要的是LAG(IGNORE NULLS)
,但SQL Server不支持。
您可以使用另一种技巧,即获取状态为0的最大日期和状态不为0的最大日期并进行比较。所以:
select t.*,
(case when statuscode = 0 then 'TRUE'
when statuscode <> 0 then 'FALSE'
when (max(case when statuscode = 0 then day end) over (order by day) >
coalesce(max(case when statuscode <> 0 day date end) over (order by day), '2000-01-01')
)
then 'TRUE'
else 'FALSE'
end) as status
from t;
Here是db <>小提琴。
您实际上可以将其简化为最后一个条件:
select t.*,
(case when (max(case when statuscode = 0 then day end) over (order by day) >
coalesce(max(case when statuscode <> 0 then day end) over (order by day), '2000-01-01')
)
then 'TRUE'
else 'FALSE'
end) as status
from t;
第一个版本更好地遵循了您所描述的逻辑。
我无法从问题中得知您是否要基于runningspeed
或statuscode
来构建逻辑。 runningspeed
的逻辑非常相似。
答案 2 :(得分:0)
使用OUTER APPLY
作为更灵活的滞后时间
实时测试:http://sqlfiddle.com/#!18/4c73f/18
select
o.*,
Status =
convert(bit,
case
when o.RunningSpeed > 0
or o.RunningSpeed is null and prev.StatusCode = 0 then
1
else
0
end)
from tbl o
outer apply
(
select top 1 StatusCode
from tbl i
where i.Day < o.Day and i.StatusCode is not null
order by i.Day desc
) prev
输出:
| Day | RunningSpeed | Statuscode | Status |
|----------------------|--------------|------------|--------|
| 2014-01-01T00:00:00Z | 55 | 0 | true |
| 2014-01-02T00:00:00Z | 60 | 0 | true |
| 2014-01-03T00:00:00Z | 58 | 0 | true |
| 2014-01-04T00:00:00Z | 61 | 0 | true |
| 2014-01-05T00:00:00Z | 57 | 0 | true |
| 2014-01-06T00:00:00Z | 56 | 0 | true |
| 2014-01-07T00:00:00Z | 60 | 0 | true |
| 2014-01-08T00:00:00Z | (null) | (null) | true |
| 2014-01-09T00:00:00Z | (null) | (null) | true |
| 2014-01-10T00:00:00Z | 55 | 0 | true |
| 2014-01-11T00:00:00Z | 56 | 0 | true |
| 2014-01-12T00:00:00Z | 60 | 0 | true |
| 2014-01-13T00:00:00Z | 0 | 20 | false |