这可能是一个新手问题,但我不能为我的生活弄清楚这一点。
在我解释我的存储过程之前,我将描述我的表并显示示例。有TicketBook
表包含已发给单位的所有TicketBooks。票票是25张票。
例如:
TicketBooks
-----------
TicketBookNum | TicketNum | UnitID | FirstTicket | LastTicket | Used
---------------------------------------------------------------------------
101 101 120 101 126 Yes
101 102 120 101 126 Yes
101 103 120 101 126 No
101 104 120 101 126 Yes
etc...
此表包含数据库中使用和未使用的所有故障单。
可以同时向不同的单位发放不同的TicketBook。因此,TicketBook 101可以发给120单元,而TicketBook 151可以发行到140.
我的存储过程需要做的是返回所有标记为未使用的故障单,但是还有一个大于标记为已使用的故障单。
示例:
TicketBookNum | TicketNum | Used
----------------------------------
101 101 Yes
101 102 Yes
101 103 No
101 104 Yes
101 105 Yes
101 106 No
101 107 No
etc..
因此存储过程返回Ticket 103
,但不返回106
和107
,因为在它们之后没有标记为Used的票证。
这是我正在使用的存储过程:
select TicketNum
from TicketBooks
where Used='No'
and TicketNum between 92226 and 92251
and TicketNum < (select top 1 TicketNum
from TicketBooks
where Used='Yes'
and TicketNum between 92226 and 92251
order by TicketNum desc)
order by TicketNum desc
这将从TicketBook 82226返回丢失的票据。如果我尝试更改between
子句上的参数,则它不会返回正确的结果。任何帮助将不胜感激。
答案 0 :(得分:2)
您可以使用公用表表达式来包装范围限制并执行存在查询,如下所示:
;with cte as (
select * from TicketBooks where TicketNum between 101 and 126
)
select * from cte where Used = 'no'
and exists (
select 1
from cte t
where t.TicketNum > cte.ticketnum
and t.used='yes'
)
这仍然局限于硬编码范围;更好的选择可能是从源表中的FirstTicket / LastTicket值构建范围。
答案 1 :(得分:1)
试试这个
;WITH cte AS
(
select TicketNum,ROW_NUMBER() OVER
(PARTITION BY TicketBookNum,Used ORDER BY TicketNum) rn
from TicketBooks
)
SELECT * FROM cte
where Used='No' AND rn =1
实施例
CREATE TABLE #t (ticket INT ,ticketno INT, fla VARCHAR(10))
INSERT INTO #t VALUES(1,1,'yes'),
(1,2,'yes'),
(1,4,'No'),
(1,5,'No')
;WITH cte AS
(
SELECT *,ROW_NUMBER() OVER(PARTITION BY ticket,fla ORDER BY ticketno) rn FROM #t
)
SELECT * FROM cte WHERE fla ='no'AND rn =1
答案 2 :(得分:1)
select TicketNum
from TicketBooks as t
where Used='No'
and TicketNum between 92226 and 92251
and exists (
select 1
from TicketBooks as t2
where t2.Used='Yes'
/* not sure if you actually want to restrict the range here */
and t2.TicketNum between 92226 and 92251
and t2.TicketNum > t.TicketNum
)
order by TicketNum desc
我无法理解您是想在票务簿或明确范围内搜索还是搜索什么。但我写这篇文章是为了向您展示EXISTS
选项。您也可能会发现< ANY (...)
和< ALL (...)
在将来有用。许多人忽略了这些。
答案 3 :(得分:1)
我相信我明白你要做什么。我认为您缺少的是您的子查询不会从外部查询映射到故障单。所以你想要这样的东西:
select TicketNum
from TicketBooks a
where Used='No'
and TicketNum < (select MAX(b.TicketNum)
from TicketBooks b
where b.Used='Yes'
and b.TicketBookNum = a.TicketBookNum)
order by TicketNum desc