似乎无法在SQL Server中解决这个问题。
两张桌子:
状态:
id proj status changedate
-------------------------------
1 1 1 2015-01-01
2 1 3 2016-01-01
3 1 2 2016-05-01
4 2 1 2016-01-01
... etc
项目:
id title active
----------------------------
1 My project 1
2 No more 0
现在我想列出所有具有最新状态ID的活动项目。我尝试了各种查询,但最终出现了错误。
在包括HAVING在内的其他解决方案中试过这个,但没有运气:
SELECT projects.id, projects.title, statuses.status
FROM projects
INNER JOIN statuses ON statuses.proj = projects.id
WHERE projects.active = 1
AND statuses.changedate = MAX(statuses.changedate)
那里有任何SQL Server向导吗?
答案 0 :(得分:4)
使用您所在的路径,您需要一个子查询:
SELECT p.id, p.title, s.status
FROM projects p INNER JOIN
statuses s
ON s.proj = p.id
WHERE p.active = 1 AND
s.changedate = (SELECT MAX(s2.changedate)
FROM statuses s2
WHERE s2.proj = p.id
);
更典型的解决方案使用ROW_NUMBER()
:
SELECT p.id, p.title, s.status
FROM projects p INNER JOIN
(SELECT s.*,
ROW_NUMBER() OVER (PARTITION BY s.proj ORDER BY s.changedate DESC) as seqnum
FROM statuses s
) s
ON s.proj = p.id AND seqnum = 1
WHERE p.active = 1;
更难以理解的方式是使用APPLY
:
SELECT p.*, s.status
FROM projects p OUTER APPLY
(SELECT TOP 1 s.*
FROM status s
WHERE s.proj = p.id
ORDER BY s.changedate DESC
) s
WHERE p.active = 1;
嗯,这是不可思议的,你以前从未见过APPLY
。
答案 1 :(得分:1)
另一种选择是使用TOP 1 WITH TIES并使用row_number()命令:
select top 1 WITH TIES
t1.status
, t1.changedate
, p.title
from statuses t1
inner join projects p on p.id = t1.proj AND p.active = 1
order by
ROW_NUMBER() OVER(PARTITION BY t1.proj ORDER BY changedate desc)
答案 2 :(得分:1)
这是来自MySql,但SqlServer
的语法应该非常相似create table status (
id int,
proj int,
status int,
change_date date
);
create table project (
id int,
title varchar(64),
active int
);
insert into status values (1,1,1,'2015-01-01');
insert into status values (2,1,3,'2015-01-01');
insert into status values (3,1,2,'2015-01-01');
insert into status values (4,2,1,'2015-01-01');
insert into project values (1,'My project', 1);
insert into project values (2,'No more', 0);
insert into project values (3,'Other project', 1);
select
p.title,
max(s.change_date)
from
project p
left outer join status s on s.proj = p.id
where
p.active = 1
group by
p.title
;
输出如下:
+ ------------- + ----------------------- +
| title | max(s.change_date) |
+ ------------- + ----------------------- +
| My project | 2015-01-01 |
| Other project | |
+ ------------- + ----------------------- +
2 rows