62,046
社区成员
发帖
与我相关
我的任务
分享
SELECT b.* FROM (
SELECT ROW_NUMBER()OVER(ORDER BY t1.ID) AS ModeID,COUNT(0)OVER(PARTITION BY 1) AS ModeCount
,t1.ID AS Line1,t2.id AS Line2,t3.id AS Line3,t4.id AS Line4,t5.id AS Line5
FROM #t AS t1
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id>t1.id AND tt.AMT+t1.AMT<=20) AS t2
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id>t2.id AND tt.AMT+t1.AMT+t2.AMT<=20) AS t3
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id >t3.id AND tt.AMT+t1.AMT+t2.AMT+t3.AMT<=20) AS t4
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id >t4.id AND tt.AMT+t1.AMT+t2.AMT+t3.AMT+t4.AMT<=20) AS t5
WHERE t1.AMT+ISNULL(t2.AMT,0) +ISNULL(t3.AMT,0) +ISNULL(t4.AMT,0) +ISNULL(t5.AMT,0) =20
) a
CROSS APPLY(VALUES(a.ModeID,Line1),(a.ModeID,Line2),(a.ModeID,Line3),(a.ModeID,Line4),(a.ModeID,Line5)) b(ModeID,LineID)
WHERE b.LineID IS NOT NULL
/*
1:选择1,3放弃2,4,5
2:选择2,4放弃1,3,5
3:选择5,放弃1,2,3,4
ModeID LineID
1 1
1 3
2 2
2 4
3 5
*/
IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
CREATE TABLE #t(ID INT,No VARCHAR(100),AMT INT,[STATUS] BIT)
GO
INSERT INTO #t(ID,NO,AMT,[STATUS])
select 1,'X1',18,1 UNION ALL
select 2,'X2',15,1 UNION ALL
select 3,'X3',2,1 UNION ALL
select 4,'X4',5,1 UNION ALL
select 5,'X5',20,1
SELECT * FROM (
SELECT sv.number,t.*,CASE WHEN c.LineID IS NULL THEN 0 ELSE 1 END AS Selected
,SUM(ISNULL(c.ModeID,0)) OVER(PARTITION BY sv.number) AS ModelLineCount
FROM #t AS t
INNER JOIN MASTER.dbo.spt_values AS sv ON sv.[type]='P' AND sv.number BETWEEN 1 AND 5
LEFT JOIN (
SELECT b.*,a.ModeCount FROM (
SELECT ROW_NUMBER()OVER(ORDER BY t1.ID) AS ModeID,COUNT(0)OVER(PARTITION BY 1) AS ModeCount
,t1.ID AS Line1,t2.id AS Line2,t3.id AS Line3,t4.id AS Line4,t5.id AS Line5
FROM #t AS t1
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id>t1.id AND tt.AMT+t1.AMT<=20) AS t2
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id>t2.id AND tt.AMT+t1.AMT+t2.AMT<=20) AS t3
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id >t3.id AND tt.AMT+t1.AMT+t2.AMT+t3.AMT<=20) AS t4
OUTER APPLY (SELECT * FROM #t AS tt WHERE tt.id >t4.id AND tt.AMT+t1.AMT+t2.AMT+t3.AMT+t4.AMT<=20) AS t5
WHERE t1.AMT+ISNULL(t2.AMT,0) +ISNULL(t3.AMT,0) +ISNULL(t4.AMT,0) +ISNULL(t5.AMT,0) =20
) a
CROSS APPLY(VALUES(a.ModeID,Line1),(a.ModeID,Line2),(a.ModeID,Line3),(a.ModeID,Line4),(a.ModeID,Line5)) b(ModeID,LineID)
WHERE b.LineID IS NOT NULL
) c ON c.LineID=t.ID AND c.ModeID=sv.number
) d WHERE d.ModelLineCount>0
ORDER BY d.number,d.ID
/*
number ID No AMT STATUS Selected ModelLineCount
1 1 X1 18 1 1 2
1 2 X2 15 1 0 2
1 3 X3 2 1 1 2
1 4 X4 5 1 0 2
1 5 X5 20 1 0 2
2 1 X1 18 1 0 4
2 2 X2 15 1 1 4
2 3 X3 2 1 0 4
2 4 X4 5 1 1 4
2 5 X5 20 1 0 4
3 1 X1 18 1 0 3
3 2 X2 15 1 0 3
3 3 X3 2 1 0 3
3 4 X4 5 1 0 3
3 5 X5 20 1 1 3
*/
--创建测试表
CREATE TABLE #
(
ID INT,
NO CHAR(2),
AMT INT,
STATUS BIT
);
--插入测试数据
INSERT INTO # VALUES
(1,'X1',18,1),
(2,'X2',15,1),
(3,'X3',2,1),
(4,'X4',5,1),
(5,'X5',20,1);
--1行的情况
update # set #.[STATUS] = 0 where not exists
(
select * from
(
select top 1 * from # where exists
(
select SUM(a.AMT) from
(
select top 1 * from # order by AMT desc
) a
having SUM(a.AMT) >= 20
) order by AMT desc
) b
where #.ID = b.ID
)
--2行的情况
update # set #.[STATUS] = 0 where not exists
(
select * from
(
select top 2 * from # where exists
(
select SUM(a.AMT) from
(
select top 2 * from # order by AMT desc
) a
having SUM(a.AMT) >= 20
) order by AMT desc
) b
where #.ID = b.ID
)
--3行的情况
update # set #.[STATUS] = 0 where not exists
(
select * from
(
select top 3 * from # where exists
(
select SUM(a.AMT) from
(
select top 3 * from # order by AMT desc
) a
having SUM(a.AMT) >= 20
) order by AMT desc
) b
where #.ID = b.ID
)
--4行的情况
update # set #.[STATUS] = 0 where not exists
(
select * from
(
select top 4 * from # where exists
(
select SUM(a.AMT) from
(
select top 4 * from # order by AMT desc
) a
having SUM(a.AMT) >= 20
) order by AMT desc
) b
where #.ID = b.ID
)
复制了 @mingqing6364 的创建表语句。--创建测试表
CREATE TABLE #
(
ID INT,
NO CHAR(2),
AMT INT,
STATUS BIT
);
--插入测试数据
INSERT INTO # VALUES
(1,'X1',18,1),
(2,'X2',15,1),
(3,'X3',2,1),
(4,'X4',5,1),
(5,'X5',20,1);
--一个数等于20
UPDATE # SET STATUS = 0 WHERE NOT EXISTS (SELECT A.ID FROM # A WHERE A.AMT = 20 AND #.ID = A.ID)
SELECT * FROM #
UPDATE # SET STATUS = 1;
--两个数等于20
UPDATE # SET STATUS = 0 WHERE NOT EXISTS (SELECT A.ID FROM # A INNER JOIN # B ON A.AMT + B.AMT = 20 WHERE #.ID = A.ID)
SELECT * FROM #
UPDATE # SET STATUS = 1;
--删除测试表
DROP TABLE #;
实际上这种需求最好使用C语言或者别的编程语言去实现,不建议使用SQL