这样的删除语句要怎么写

小野马1209 2018-01-22 04:15:55
业务描述:
第一行数据,4月30应收A客户100元,应收合计为100
第二行数据,5月30收到A客户100元,应收合计为0
第三行数据,6月30应收A客户300元,应收合计为300
第四行数据,7月30应收A客户500元,应收合计为800

需求描述:
按日期排序(升序),金额为0及之前的数据删除,如案例,删除后只保留第三条和第四条

DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800

--SELECT * FROM @T
...全文
392 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
小野马1209 2018-02-26
  • 打赏
  • 举报
回复
引用 6 楼 yenange 的回复:
改一下:
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH lt0 as ( 
SELECT 客户代码,max(日期) as 日期 FROM @T
WHERE 合计<=0
GROUP BY 客户代码
)
SELECT * FROM @t a WHERE EXISTS(
	SELECT 1 FROM lt0 AS b 
	WHERE
	a.客户代码=b.客户代码
	AND	a.日期>b.日期
)
/*
客户代码	日期	发生额	合计
A	20170630	300.000000	300.000000
A	20170730	500.000000	800.000000
*/

如果再加一个B客户呢,按这种写法B就会漏了,因为金额>0
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 union ALL
SELECT 'B',20170730,1000,1000 
小野马1209 2018-02-26
  • 打赏
  • 举报
回复
引用 6 楼 yenange 的回复:
改一下:
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH lt0 as ( 
SELECT 客户代码,max(日期) as 日期 FROM @T
WHERE 合计<=0
GROUP BY 客户代码
)
SELECT * FROM @t a WHERE EXISTS(
	SELECT 1 FROM lt0 AS b 
	WHERE
	a.客户代码=b.客户代码
	AND	a.日期>b.日期
)
/*
客户代码	日期	发生额	合计
A	20170630	300.000000	300.000000
A	20170730	500.000000	800.000000
*/

如果数据再加一条客户呢 ,金额没有小于=0的
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 union ALL
SELECT 'B',20170730,1000,1000 
小野马1209 2018-01-22
  • 打赏
  • 举报
回复
引用 7 楼 kaijie_wu1209 的回复:
[quote=引用 1 楼 qq_37170555 的回复:]

DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH cte AS (
	SELECT * ,row_number() over(ORDER BY 日期) as rn FROM @T
)
--删除
DELETE FROM cte WHERE rn<=(
	SELECT rn FROM cte WHERE 合计=0
)
SELECT * FROM @t
如果案例中存在两条为0的数据就会有问题,不过逻辑知道了,谢谢[/quote] 哈哈。不敢,是我案例没写这种情况,这样同样可以学习你的这种思路
听雨停了 2018-01-22
  • 打赏
  • 举报
回复
引用 7 楼 kaijie_wu1209 的回复:
[quote=引用 1 楼 qq_37170555 的回复:]

DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH cte AS (
	SELECT * ,row_number() over(ORDER BY 日期) as rn FROM @T
)
--删除
DELETE FROM cte WHERE rn<=(
	SELECT rn FROM cte WHERE 合计=0
)
SELECT * FROM @t
如果案例中存在两条为0的数据就会有问题,不过逻辑知道了,谢谢[/quote] 那是因为你还要按照客户来分组得到row_number,所以有问题。你之前也没说,所以就写成这样喽,怪我喽
小野马1209 2018-01-22
  • 打赏
  • 举报
回复
引用 1 楼 qq_37170555 的回复:

DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH cte AS (
	SELECT * ,row_number() over(ORDER BY 日期) as rn FROM @T
)
--删除
DELETE FROM cte WHERE rn<=(
	SELECT rn FROM cte WHERE 合计=0
)
SELECT * FROM @t
如果案例中存在两条为0的数据就会有问题,不过逻辑知道了,谢谢
吉普赛的歌 2018-01-22
  • 打赏
  • 举报
回复
改一下:
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH lt0 as ( 
SELECT 客户代码,max(日期) as 日期 FROM @T
WHERE 合计<=0
GROUP BY 客户代码
)
SELECT * FROM @t a WHERE EXISTS(
	SELECT 1 FROM lt0 AS b 
	WHERE
	a.客户代码=b.客户代码
	AND	a.日期>b.日期
)
/*
客户代码	日期	发生额	合计
A	20170630	300.000000	300.000000
A	20170730	500.000000	800.000000
*/

吉普赛的歌 2018-01-22
  • 打赏
  • 举报
回复
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800 

;WITH lt0 as ( 
SELECT 客户代码,max(日期) as 日期 FROM @T
WHERE 发生额<0
GROUP BY 客户代码
)
SELECT * FROM @t a WHERE EXISTS(
	SELECT 1 FROM lt0 AS b 
	WHERE
	a.客户代码=b.客户代码
	AND	a.日期>b.日期
)
/*
客户代码	日期	发生额	合计
A	20170630	300.000000	300.000000
A	20170730	500.000000	800.000000
*/

小野马1209 2018-01-22
  • 打赏
  • 举报
回复
引用 2 楼 sinat_28984567 的回复:
如果两条为0的呢?以最后一条为主,前边的都删除?
是的,都删除
二月十六 2018-01-22
  • 打赏
  • 举报
回复
如果两条为0的呢?以最后一条为主,前边的都删除?
二月十六 2018-01-22
  • 打赏
  • 举报
回复
如果是这样的话,可以这样写
DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800


DELETE FROM @T
WHERE 日期 <= ( SELECT MAX(日期) AS 日期
FROM @T
WHERE 合计 = 0
)

SELECT * FROM @T


听雨停了 2018-01-22
  • 打赏
  • 举报
回复

DECLARE @T TABLE(客户代码 varchar(50),日期 int,发生额 numeric(19,6),合计 numeric(19,6))
INSERT INTO @T
SELECT 'A',20170430,100,100 UNION ALL
SELECT 'A',20170530,-100,0 UNION ALL
SELECT 'A',20170630,300,300 UNION ALL
SELECT 'A',20170730,500,800

;WITH cte AS (
SELECT * ,row_number() over(ORDER BY 日期) as rn FROM @T
)
--删除
DELETE FROM cte WHERE rn<=(
SELECT rn FROM cte WHERE 合计=0
)
SELECT * FROM @t

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧