我想编写一个SQL查询(SQL Server),它将返回行(按给定的顺序),但只返回给定的总数。我的客户已付给我一定的金额,我想只返回那些< =到那个金额的行。
例如,如果客户付了我370美元,表中的数据是
id amount
1 100
2 122
3 134
4 23
5 200
然后我想只返回第1,2和3行
这需要高效,因为会有数千行,所以for循环不是理想的,我想。或者SQL Server是否足够高效以使用for循环优化存储过程?
提前致谢。吉姆。
答案 0 :(得分:3)
有两种选择。
1)三角连接
SELECT *
FROM YourTable Y1
WHERE (SELECT SUM(amount)
FROM YourTable Y2
WHERE Y1.id >= Y2.id ) <= 370
2)递归CTE
WITH RecursiveCTE
AS (
SELECT TOP 1 id, amount, CAST(amount AS BIGINT) AS Total
FROM YourTable
ORDER BY id
UNION ALL
SELECT R.id, R.amount, R.Total
FROM (
SELECT T.*,
T.amount + Total AS Total,
rn = ROW_NUMBER() OVER (ORDER BY T.id)
FROM YourTable T
JOIN RecursiveCTE R
ON R.id < T.id
) R
WHERE R.rn = 1 AND Total <= 370
)
SELECT id, amount, Total
FROM RecursiveCTE
OPTION (MAXRECURSION 0);
第二个可能表现更好。
在SQL Server 2012中,您将能够像
这样的东西;WITH CTE AS
(
SELECT id,
amount,
SUM(amount) OVER(ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS RunningTotal
FROM YourTable
)
SELECT *
FROM CTE
WHERE RunningTotal <=370
虽然可能会有更有效的方法(一旦达到总数就停止扫描)
答案 1 :(得分:0)
直接进场:
SELECT a.id, a.amount
FROM table1 a
INNER JOIN table1 b ON (b.id <=a.id)
GROUP BY a.id, a.amount
HAVING SUM(b.amount) <= 370
不幸的是,它有N ^ 2性能问题。
答案 2 :(得分:0)
类似的东西:
select id from
(
select t1.id, t1.amount, sum( t2.amount ) s
from tst t1, tst t2
where t2.id <= t1.id
group by t1.id, t1.amount
)
where s < 370