表名= t1
ID | FileID | Status
1 | 3 | NO
3 | 5 | YES
4 | 3 | NO
表名= T2
ID | FileID | From stage| Date | Remark
1 | 3 | 14 | 20/03/2015 | file is submitted
2 | 3 | 14 | 21/03/2015 | file is not completed
3 | 5 | 14 | 20/03/2015 | file is submitted
仅当文件ID 没有“状态
时,我才想要最新日期条目的T2表格详细信息使用以下查询
select *
from (select distinct(t1.FileID)
from t1
where t1.FileID not in (select FileID from t1 where Status='YES')
) c1 ,t2
where t2.FileID=c1.FileID and t2.FromStageID='14
order by c1.FileID
获得结果
FIleID | ID | FileID | From stage| Date | Remark
3 | 1 | 3 | 14 | 20/03/2015 | file is submitted
3 | 2 | 3 | 14 | 21/03/2015 | file is not completed
我想要什么
FIleID | ID | FileID | From stage| Date | Remark
3 | 2 | 3 | 14 | 21/03/2015 | file is not completed
答案 0 :(得分:2)
传统上是SQL-Server的cross apply
版本:
SELECT
tt.*
FROM
T1
cross apply (
SELECT TOP 1 *
from t2
WHERE t2.fileId = t1.FileId
ORDER BY t2.date DESC
) TT
WHERE T1.status = 'YES'
这将产生最佳性能,同时更难理解并需要学习新的操作员(如果还没有)
编辑:虽然下面的查询产生了更糟糕的执行计划(仍然不是非常糟糕),但更容易阅读。对于具有< 100k记录的表:
,仍然可以很好地执行SELECT
t2.FileId, T2.FromStage, T2.Date, T2.remark
FROM
T1 JOIN T2 ON T2.FileId = T1.FileId
WHERE T1.status = 'YES' AND
T2.Date = (SELECT MAX(T2.Date) FROM T2 WHERE T1.FileId = T2.FileId)
答案 1 :(得分:1)
如果你想要最新的东西,请考虑row_number()
,然后根据条件获取第一个。
以下使用left join
代替not in
来查找fileid
中没有相应匹配项的t1
。这样更安全,因为not in
对NULL
值的行为非直观。
此外,永远不要在from
子句中使用逗号。这是一个简单的规则。始终使用明确的join
语法。
select t.*
from (select t2.*,
row_number() over (partition by fileid order by date desc) as seqnum
from t2 left join
t1
on t2.fileid = t1.fileid and t1.status = 'YES'
where t1.fileid is null
) t
where seqnum = 1;
答案 2 :(得分:0)
另一个原因,您可以使用CommonTableExpression
和ROW_NUMBER()
来实现此结果:
试试这个:Fiddle Demo Here
create table t1(
ID int,
FieldId int,
[Status] varchar(50)
)
insert into t1 values(1,3,'NO'),(3,5,'YES'),(4,3,'NO')
create table T2(
Id int,
FieldId int,
From_Stage int,
date1 date,
Remarks varchar(50)
)
insert into T2 values(1,3,14,'03/20/2015','file is submitted'),
(2,3,14,'03/21/2015','file is not completed'),
(3,5,14,'03/21/2015','file is submitted')
查询:
;with cte as
(
select t1.FieldId,t2.ID,t2.From_Stage,t2.date1,t2.REmarks,
ROW_NUMBER() Over(PARTITION by t2.FieldId order by t2.date1 desc) as rk
from t1,T2 t2 where t1.FieldId=t2.FieldId and t1.Status!='YES'
)
select * from cte where rk=1