2

我需要一个 select 语句,它将询问总计列表并确定结果集中是否存在等于局部变量的加法组合。

例子:

create table #mytemptable
(
totals Decimal (19,2)
)

insert into #mytemptable (totals)
values (57.83),
            (244.18),
            (239.23), 
            (227.79),
            (563.12)  

select *
from #mytemptable

在此处输入图像描述

我现在想检查添加时结果中的任何组合是否相等

285.62

此外,如果有多个实例可以添加总计以等于我的变量,那么这将被处理并以适当的方式显示。

4

2 回答 2

2

有点令人费解,但在这里:

基本上,我的目标是生成一个动态查询,其中一列将标识值(A 列上的第一个值,B 列上的第二个值等),最后是一个包含总数的列。

之后,我们可以使用 cube 进行分组,这将对按不同列分组的值的所有排列求和。查看示例

最终结果将显示如下:

Total   A     B  C   D  E
285.62 NULL NULL NA NA NA

这将表明 285.62 是第一个和第二个值的总和,按值排序

DECLARE @columns varchar(max) = ''
DECLARE @allcolumns varchar(max) = ''
DECLARE @columnName varchar(1) = 'A'
DECLARE @select varchar(max) = ''

SELECT 
    @columns = @columns + ',''NA'' AS ' + @columnName, 
    @allcolumns = @allcolumns + ',' + @columnName,
    @columnName = CHAR(ASCII(@columnName)+1)
FROM
#mytemptable

SET @columnName = 'A'

SELECT
@select = @select + CHAR(13) + 'UNION SELECT ' + CONVERT(varchar(100),totals) + ' AS totals' + STUFF(@columns,2+10*(ord-1),4,'''' + @columnName + ''''), @columnName = CHAR(ASCII(@columnName)+1)
FROM
(SELECT totals, ROW_NUMBER() OVER(ORDER BY totals) ord from #mytemptable)
A



SET @select = STUFF(@select,1,6,'')
SET @allcolumns = STUFF(@allcolumns, 1,1,'')

--PRINT (@select)
EXEC ( 'SELECT * FROM (
        SELECT SUM(totals) AS Total, ' + @allcolumns + ' 
        FROM (' + @select + ') A GROUP BY ' + @allcolumns + ' WITH CUBE
        ) sub WHERE Total = 285.62 ')
于 2013-07-04T11:37:54.240 回答
0

如果您愿意在表中添加标识列,则以下 CTE 解决方案将适合您:

WITH SumOfPermutations AS
(
  SELECT
    CONVERT(decimal(15,2), 0) SummedTotals,
    0 id
  UNION ALL
  SELECT
    CONVERT(decimal(15,2), A.SummedTotals + B.totals),
    B.ID
  FROM
    SumOfPermutations A
    INNER JOIN myTempTable B ON A.ID < B.ID AND A.SummedTotals + B.Totals <= 285.62
  WHERE
    A.SummedTotals + B.totals <= 285.62    
  )
SELECT
  COUNT(*) 
FROM 
  SumOfPermutations
WHERE 
  SummedTotals = 285.62

但是请注意,如果您有大量的小值,性能将大大降低。这是因为一旦排列的总和高于 285.62,它就不再包括在内。如果您有很多小的值,那么在达到 285.62 阈值之前,您将有很多具有大量值的排列。如果您的真实数据的分布与您提供的示例数据类似,那么这应该可以很好地快速运行。

如果您希望表中可以汇总为低于 285.62 的值的大多数数字约为 10,那么您应该没问题。但是,如果您的表中有 20 个值低于 30.0,您可能会遇到问题。

于 2013-07-04T13:47:54.760 回答