2

我会做一个 sql 语句来检索所有的图像,只要大小的总和是 100

我有这个:

SELECT PhotoNr
INTO # PhotoTabl
FROM Photo
WHERE Size <= 100????

ORDER BY PhotoOrder ASC

表格内容:

PhotoNr ...... Size
1 ............ 20
2 ............ 50
3 ............ 20
4 ............ 50
5 ............ 20

sql会给出结果:

PhotoNr ...... Size
1 ............ 20
2 ............ 50
3 ............ 20

有什么好的解决方案吗?

4

3 回答 3

3

有很多方法可以给这只猫剥皮。最好的将取决于您可以使用什么,以及大小等所施加的限制

一种选择是使用递归 CTE(这个简单的例子假设连续的 photonr 值,如果需要可以允许不连续的值):

;WITH CTE as (
  select PhotoNr, Size, Tot = Size
  from photos where photonr = 1
  union all
  select p.PhotoNr, p.Size, Tot = cte.Tot +p.Size
  from CTE
  join photos p on CTE.PhotoNr + 1 = p.photonr
  )
select photonr, size from cte
where tot < 100

SQL小提琴在这里

或者,一种非常简单的方法(编码)(但可能不是那么高效)可以使用cross apply

select
  photonr,
  size
from photos p
  cross apply (
    select tot = sum(size) from photos sub
    where sub.photonr <= p.photonr) x
where tot <= 100

另一个 SQL 小提琴在这里

于 2013-07-12T22:46:15.440 回答
3

PhotoNr如果您使用的是 SQL Server 2012+,则有一个包含键列的索引,Size并且预期返回的行数相对于表中的行数来说很小。

WITH P
     AS (SELECT *,
                SUM(Size) OVER (ORDER BY PhotoNr  
                                ROWS UNBOUNDED PRECEDING) AS RunningCount
         FROM   Photo)
SELECT *
FROM   Photo
WHERE  PhotoNr < (SELECT TOP 1 PhotoNr
                  FROM   P
                  WHERE  RunningCount > 100
                  ORDER  BY PhotoNr) 
于 2013-07-12T22:56:09.850 回答
0

正如@MartinSmith评论中所说,您只需要计算一个运行总计。有很多方法,取决于您的 RDBMS,您可以利用什么来提高效率等。一种基本但非常低效的方法是这样的。

WITH cte AS
(
    SELECT p1.id, p1.size, SUM(p2.size) running_total
    FROM photos p1, photos p2
    WHERE p1.id >= p2.id
    GROUP BY p1.id, p1.size
)

SELECT id, size
FROM cte 
WHERE running_total <= 100

有一篇有趣的文章比较了创建运行总计的方法here

于 2013-07-12T22:46:25.387 回答