我有一个像这样的行的表:
ID StatusId Date
1 1 2001-01-01
2 1 2001-01-02
3 2 2001-01-03
4 3 2001-01-04
5 1 2001-01-05
6 2 2001-01-06
7 2 2001-01-07
8 1 2001-01-08
9 1 2001-01-09
我需要获取状态的当前值最初更改时的日期。对于上面的示例,最后一个值是1,它在第8行中更改,因此结果将是2001-01-08。
你会怎么做?
如果你需要一个表来测试,这里是:
DECLARE @Tbl AS TABLE (ID INT, StatusId INT, Date DATETIME)
INSERT INTO @Tbl(ID, StatusId, Date)
SELECT 1,1,'2001-01-01' UNION
SELECT 2,1,'2001-01-02' UNION
SELECT 3,2,'2001-01-03' UNION
SELECT 4,3,'2001-01-04' UNION
SELECT 5,1,'2001-01-05' UNION
SELECT 6,2,'2001-01-06' UNION
SELECT 7,2,'2001-01-07' UNION
SELECT 8,1,'2001-01-08' UNION
SELECT 9,1,'2001-01-09'
SELECT * FROM @Tbl
答案 0 :(得分:2)
这样的事情:
DECLARE @CurrentID INT, @CurrentDate Date
SELECT TOP 1 @CurrentID = ID, @CurrentDate = Date FROM TABLE
ORDER BY Date DESC
SELECT TOP 1 ID, StatusID, Date
FROM Table
WHERE Date < @CurrentDate
AND ID <> @CurrentID
ORDER BY Date DESC
答案 1 :(得分:2)
这个应该能让你得到你想要的东西:
declare @LastStatusID int
declare @LastDate datetime
declare @LastID int
declare @LastChangeID int
/* get last record */
select top 1 @LastStatusID = StatusID, @LastDate = Date, LastID = ID
from @Tbl
order by ID desc
/* get last record with a different status */
select top 1 @LastChangeID = ID
from @Tbl
where ID < @LastID and StatusID <> @LastStatusID
order by ID desc
/* get the first next record - this would get you the last record as well whe it's just been set */
select top 1 Date
from @Tbl
where ID > @LastChangeID
order by ID asc
当表中只有一条记录或多条记录但状态相同时,我没有包括任何边距示例的检查。你可以自己解决这些问题。
此查询需要没有间隙的ID,它会在状态更改后获取最后一条记录>>当表中只有一条记录或其中多条记录具有相同状态时,它也会起作用( isnull
提供所需的功能)
select top 1 Date
from @tbl t1
left join @tbl t2
on (t2.ID = t1.ID - 1)
where (isnull(t2.StatusID, -1) <> t1.StatusID)
order by ID desc
上一个where
子句将null
值(当没有上记录时)更改为-1
。如果您的状态具有此值,则应将此数字更改为某个不存在的状态值。
答案 2 :(得分:0)
尝试
select Date
from @Tbl
where StatusId = (
select StatusId
from @Tbl
order by ID desc limit 1)
order by ID desc
limit 1,1
请检查您的数据库是否支持限制。如果不使用它的等价物(例如Top)。
我按照mysql编写了这个。
答案 3 :(得分:0)
如果表格保证每天有一个条目(根据您的样本数据),则以下内容可能有效
select MAX(t1.Date)
from
@Tbl t1
inner join
@Tbl t2
on
t1.Date = DATEADD(day,1,t2.Date) and
t1.StatusId <> t2.StatusID
当然,如果有其他列/标准,如果值可能永远不会发生变化,则可以进一步细化。使用小样本量/输出示例很难说清楚。
编辑1 如果我每天的一个条目假设错误,那么from子句可以是:
from
@Tbl t1
inner join
@Tbl t2
on
t1.Date > t2.Date and
t1.StatusId <> t2.StatusID
left join
@Tbl t_successive
on
t1.Date > t_successive.Date and
t2.Date < t_successive.Date
where
t_successive.ID is null
(使用左连接确保t1和t2中的行之间没有任何其他行)
答案 4 :(得分:0)
这是我最终提出的:
SELECT T1.ID, T1.StatusId, MIN(T3.Date)
FROM @Tbl T1 INNER JOIN @Tbl T3 ON T1.StatusId = T3.StatusId
WHERE T3.Date > (SELECT MAX(Date) FROM @Tbl T2 WHERE T2.StatusId <> T1.StatusId)
AND T1.ID = (SELECT MAX(ID) FROM @Tbl)
GROUP BY T1.ID, T1.StatusId
它正在做我需要它...感谢所有人