我有一个包含以下列的表:Author_name,国家/地区和状态。
Author_name country status
-------------------------------------------
1 Author - 1 Country - 1 name remove
2 Author - 2 Country - 2 name done
3 Author - 3 Country - 3 name done
4 Author - 4 Country - 4 name done
5 Author - 5 Country - 5 name done
6 Author - 6 Country - 6 name remove
7 Author - 7 Country - 7 name remove
8 Author - 8 Country - 8 name done
9 Author - 9 Country - 9 name remove
10 Author - 10 Country - 10 name done
预期功能:遇到“删除”时,必须删除该行,并删除其上方的行。
如果“删除”连续出现,则必须删除顶部的许多行。 “删除”的位置和记录数不是恒定的。
一旦运行了SQL脚本,上表的输出应为:
Author_name country status
-------------------------------------------
2 Author - 2 Country - 2 name done
3 Author - 3 Country - 3 name done
10 Author - 10 Country - 10 name done
希望您了解逻辑。
我尝试使用滞后,光标和其他一些方法。现在我正在尝试while循环。请帮我解决一下这个。这是我的最新代码。
我的数据库是SQL Server,当前正在使用在线编译器:https://rextester.com/l/sql_server_online_compiler
CREATE Table tblAuthors
(
Author_name nvarchar(50),
country nvarchar(50),
prod varchar(50),
timestamp datetime
)
Declare @Id int
Set @Id = 1
While @Id <= 10
Begin
Insert Into tblAuthors values ('Author - ' + CAST(@Id as nvarchar(10)),
'Country - ' + CAST(@Id as nvarchar(10)) + ' name', 'done', getdate())
Print @Id
Set @Id = @Id + 1
End
update tblAuthors set prod = 'remove' where Author_name = 'Author - 1'
update tblAuthors set prod = 'remove' where Author_name = 'Author - 6'
update tblAuthors set prod = 'remove' where Author_name = 'Author - 7'
update tblAuthors set prod = 'remove' where Author_name = 'Author - 9'
SELECT * FROM tblAuthors
select IDENTITY(int, 1,1) as idnt,* into ##temp_tblAuthors from tblAuthors
select * from ##temp_tblAuthors
DECLARE @intFlag INT = 1
DECLARE @Flag INT = 0
DECLARE @Author_name nvarchar(50)
DECLARE @country nvarchar(50)
DECLARE @prod varchar(50)
DECLARE @idnt INT
select @Flag = count(*) from ##temp_tblAuthors
WHILE (@intFlag <=@Flag)
BEGIN
select
@idnt = idnt
,@Author_name = Author_name
,@country = country
,@prod = prod
from ##temp_tblAuthors where idnt = @intFlag
if @prod = 'remove'
BEGIN
SELECT @intFlag
select
@idnt = idnt
,@Author_name = Author_name
,@country = country
,@prod = prod
from ##temp_tblAuthors where idnt = @intFlag-1
DELETE tblAuthors WHERE
Author_name = @Author_name AND
country = @country AND
prod = @prod
select
@idnt = idnt
,@Author_name = Author_name
,@country = country
,@prod = prod
from ##temp_tblAuthors where idnt = @intFlag
DELETE tblAuthors WHERE
Author_name = @Author_name AND
country = @country AND
prod = @prod
END
SET @intFlag = @intFlag + 1
END
GO
SELECT * FROM tblAuthors
答案 0 :(得分:1)
如果您 后退 ,则可以总计“得分”,其中'remove'
有-1
,而'done'
有{ {1}}。
+1
示例SQL:
Author_name Country Status Score
------------------------------------------------------
1 Author - 1 Country - 1 name remove 2
2 Author - 2 Country - 2 name done 3
3 Author - 3 Country - 3 name done 2
4 Author - 4 Country - 4 name done 1
5 Author - 5 Country - 5 name done 0
6 Author - 6 Country - 6 name remove -1
7 Author - 7 Country - 7 name remove 0
8 Author - 8 Country - 8 name done 1
9 Author - 9 Country - 9 name remove 0
10 Author - 10 Country - 10 name done 1 <- Start from here
然后,您只想保留比当前得分高的行(仍在向后移动)。
SELECT
*,
SUM(CASE WHEN status = 'remove' THEN -1 ELSE 1 END)
OVER (ORDER BY timestamp DESC, id DESC)
AS score
FROM
tblAuthors
您可以使用...
Author_name Country Status Score PreviousMax
--------------------------------------------------------------------
1 Author - 1 Country - 1 name remove 2 3
2 Author - 2 Country - 2 name done 3 2 <- KEEP
3 Author - 3 Country - 3 name done 2 1 <- KEEP
4 Author - 4 Country - 4 name done 1 1
5 Author - 5 Country - 5 name done 0 1
6 Author - 6 Country - 6 name remove -1 1
7 Author - 7 Country - 7 name remove 0 1
8 Author - 8 Country - 8 name done 1 1
9 Author - 9 Country - 9 name remove 0 1
10 Author - 10 Country - 10 name done 1 NULL <- KEEP
这也导致您...
WITH
scored_rows AS
(
SELECT
*,
SUM(CASE WHEN status = 'remove' THEN -1 ELSE 1 END)
OVER (ORDER BY timestamp DESC, id DESC)
AS score
FROM
tblAuthors
),
checked_scored_rows AS
(
SELECT
*,
MAX(score)
OVER (ORDER BY timestamp DESC, id DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
)
AS previous_max_score
FROM
scored_rows
)
SELECT
*
FROM
checked_scored_rows
WHERE
score > COALESCE(previous_max_score, 0)
;
我相信这可以说明您想要什么:https://rextester.com/ZNNB32798