我在sql server 2005中有这个表:
id student active
1 Bob 1
3 Rob 0
5 Steve 1
7 John 1
8 Mark 0
10 Dave 0
16 Nick 1
我的选择查询按给定的ID返回活动学生。 但我也希望返回上一个和下一个活跃的学生的ID。如果没有prev,则为0或null。下一个相同。
示例:对于id = 5,我的选择将返回
id student prev_id next_id
5 steve 1 7
示例:对于id = 7,我的选择将返回
id student prev_id next_id
7 John 5 16
示例:对于id = 16,我的选择将返回
id student prev_id next_id
16 Nick 7 0
如何编写此选择查询?
我有查询,但我无法正确获取prev id。它总是返回第一个活动ID。
由于
修改: 这是我现在的查询。
select id, student,
(select top 1 id from test where id<7 and active=1) as prev,
(select top 1 id from test where id>7 and active=1) as next
from test where id=7--I used 7 just as an example. it will be a parameter
答案 0 :(得分:5)
尝试这样的事情
SELECT ID,
Student,
( SELECT TOP 1
ID
FROM dbo.table AS pT
WHERE pT.ID < T.ID And Active = 1
ORDER BY ID DESC
) AS PrevID,
( SELECT TOP 1
ID
FROM dbo.table AS pT
WHERE pT.ID > T.ID And Active = 1
ORDER BY ID
) AS NextID
FROM dbo.table AS T
答案 1 :(得分:2)
工作样本
DECLARE @T TABLE (id int, student varchar(10), active bit)
insert @t select
1 ,'Bob', 1 union all select
3 ,'Rob', 0 union all select
5 ,'Steve', 1 union all select
7 ,'John', 1 union all select
8 ,'Mark', 0 union all select
10 ,'Dave', 0 union all select
16 ,'Nick', 1
---- your query starts below this line
declare @id int set @id = 5
select id, student,
isnull((select top(1) Prev.id from @T Prev
where Prev.id < T.id and Prev.active=1
order by Prev.id desc),0) Prev,
isnull((select top(1) Next.id from @T Next
where Next.id > T.id and Next.active=1
order by Next.id),0) Next
from @T T
where id = @id
当没有匹配时,ISNULL将返回0 - NULL可以正常工作但是当没有Next
时你的问题为0。
答案 2 :(得分:1)
答案 3 :(得分:1)
您可以使用嵌套查询。我显然无法测试这一点,但你应该明白这一点。
SELECT id, student ,
(SELECT C1.id FROM students S1 WHERE S1.active = 1 AND S1.id < S.id LIMIT 1) AS beforeActive,
(SELECT C2.id FROM categories S2 WHERE S2.active = 1 AND S2.id > S.id LIMIT 1) AS afterActive
FROM students S
效率方面,我不知道此查询的执行情况
答案 4 :(得分:0)
这将为您提供更多控制,特别是因为您正在进行分页。
WITH NumberedSet AS (
SELECT s.id,
s.student,
row_number() OVER (ORDER BY s.id) AS rownum
FROM dbo.students AS s
WHERE s.active = 1
)
SELECT cur.id,
cur.student,
isnull(prv.id,0) AS prev_id,
isnull(nxt.id,0) AS next_id
FROM NumberedSet AS cur
LEFT JOIN NumberedSet AS prv ON cur.rownum - 1 = prv.rownum
LEFT JOIN NumberedSet AS nxt ON cur.rownum + 1 = nxt.rownum
;