![](/img/trans.png)
[英]SQL Server SELECT first occurrence OR if no occurrence SELECT other criteria
[英]Select first occurrence of value after last occurrence of other value in SQL
我需要找到零件的當前操作。 我必須從完成(1)或0的操作狀態列表中獲取此信息的表。因此該表通常如下所示:
ID Operation Status
1 100 1
2 200 1
3 250 1
4 300 0
5 350 0
所以在這種情況下,操作 300 是我使用 MIN(Operation) WHERE Status = 0 獲得的當前操作。
但是,出現了一些跳過某些操作的情況,如下所示:
ID Operation Status
1 100 1
2 200 0
3 250 1
4 300 0
5 350 0
所以在這種情況下,當前操作仍然是 Operation 300,但 MIN(Operation) 不起作用。 我需要的是在最后一次出現 Status = 1 行之后出現 Status = 0 的行。 我怎么能做到這一點?
編輯:還必須考慮所有操作都是狀態 0 的情況,其中正確的結果將是第一行(操作 100)
我敢肯定有一個聰明的 window function 方法來做到這一點,但在香草 sql 這就是想法
SELECT MIN(Operation)
FROM SOME_TABLE
WHERE Operation >
( SELECT MAX(Operation)
FROM SOME_TABLE
WHERE status = 1
)
這將為您提供整行:
DECLARE @MyTable TABLE (
ID INT,
Operation INT,
Status BIT
);
INSERT INTO @MyTable VALUES
(1, 100, 1)
,(2, 200, 0)
,(3, 250, 1)
,(4, 300, 0)
,(5, 350, 0)
;
WITH MaxOperation AS (
SELECT MAX(x.Operation) AS MaxOperation
FROM @MyTable x
WHERE x.Status = 1
)
SELECT TOP 1 t.*
FROM @MyTable t
CROSS APPLY (SELECT MaxOperation FROM MaxOperation) x
WHERE t.Operation > x.MaxOperation
OR x.MaxOperation IS NULL
ORDER BY t.Operation
這將導致:
ID Operation Status
----------- ----------- ------
4 300 0
如果所有的Status
值都是0
,它也會產生這個:
ID Operation Status
----------- ----------- ------
1 100 0
正如用戶 Error_2646 所指出的,一個好的方法是
select
min(ID)
from
[YourTable]
where
ID > (select max(ID) from [YourTable] where Status = 1)
我希望這個答案能給你正確的答案。 如果您可以在圖像中添加預期的 output,則更容易識別您需要什么。 請在時添加架構和數據,以便用戶放置他們的解決方案。
Schema and data I used:
(
ID INT
,operation INT
,Status INT
)
insert into Occurances values(1,100,1)
insert into Occurances values(2,200,0)
insert into Occurances values(1,250,1)
insert into Occurances values(1,300,0)
insert into Occurances values(1,350,0)
SELECT *
FROM
(
SELECT
Rank() OVER ( ORDER BY operation) AS [rank]
,MIN([operation]) AS [min]
,id
,[status]
FROM Occurances
WHERE [Status]= 0
GROUP BY id
,[status]
,operation
UNION
SELECT
Rank() OVER ( ORDER BY operation DESC) AS [rank]
,MAX([operation]) AS [min]
,id
,[status]
FROM Occurances
WHERE [Status]= 1
GROUP BY id
,[status]
,operation
) AS A
WHERE A.[rank]= 1
您可以使用 window function 非常有效地做到這一點:
SELECT TOP (1) *
FROM (
SELECT *, LEAD(Status) OVER (ORDER BY Operation DESC) AS PreviousStatus
FROM myTable
)
WHERE Status = 0 AND PreviousStatus = 1
ORDER BY Operation DESC
嘗試這個:
DECLARE @Table TABLE
(
ID int
, Operation int
, [Status] bit
)
;
INSERT INTO @Table (ID, Operation, [Status])
VALUES
(1, 100, 1)
, (2, 200, 0)
, (3, 250, 1)
, (4, 300, 1)
, (5, 350, 0)
;
SELECT TOP 1 T.*
FROM @Table T
WHERE T.[Status] = 0
AND T.ID > (
SELECT TOP 1 T.ID
FROM @Table T
WHERE T.[Status] = 1
ORDER BY ID DESC
)
ORDER BY ID
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.