Sql 查询:求和,table 中所有可能的行组合
Sql Query : Sum , all the possible combination of rows in a table
SQL 服务器 2008 R2
样本Table结构
create table TempTable
(
ID int identity,
value int
)
insert into TempTable values(6)
insert into TempTable values(7)
insert into TempTable values(8)
insert into TempTable values(9)
insert into TempTable values(10)
我真的想要这样的东西
它 returns 行使得它具有所有剩余行的总和,如下所示。
6+7
6+8
6+9
6+10
6+7+8
6+7+9
6+7+10
6+8+9
6+8+10
6+9+10
6+7+8+9
6+7+8+9+10
AronLS 解决方案满足我的需求。但是,请将问题开放几天。
1. 有 another/better 方法可以做到这一点吗?
这是一个 "all possible permutations" 问题,可以通过自连接和递归 CTE 解决。
With selfrec as (
Select t.Value, t.ID, 0 as Level From TempTable t
UNION ALL
Select t2.Value + t1.Value as Value, t1.ID, Level + 1 From TempTable t1
Inner Join selfrec t2 on t1.ID < t2.ID
Where Level < 4 -- limit the number of recursions
)
Select * From selfrec
Order By Level
此标准消除了与自身匹配的项目,以及排列组合的重复反转:
t1.ID < t2.ID
限制递归的深度,因为我们没有其他突破标准,并且将超过允许的递归数:
Where Level < 4
FWIW--
稍微点缀一下,就知道是怎么回事了:
CREATE TABLE #TempTable
(
Expr VARCHAR(10),
ID INT IDENTITY,
value INT
)
INSERT INTO #TempTable VALUES('6', 6) -- a
INSERT INTO #TempTable VALUES('7', 7) -- b
INSERT INTO #TempTable VALUES('8', 8) -- c
INSERT INTO #TempTable VALUES('9', 9) -- d
INSERT INTO #TempTable VALUES('10', 10) -- e
SELECT expr, value FROM #TempTable
-- Choose(n,k) = n!/(n!(n-k)!) [order not important]
-- n = 5, k = {1,2,3,4,5}
-- C(5,1) + C(5,2) + C(5,3) + C(5,4) + C(5,5)
-- 5 + 10 + 10 + 5 + 1 = 31
-- There should be 31 rows.
------
;
WITH selfrecCTE AS
(
SELECT
CAST(expr AS VARCHAR(100)) AS Expr
, T.value
, T.ID
, 0 AS Level
FROM
#TempTable AS T
UNION ALL
SELECT
CAST(t1.expr + ' + ' + T2.expr AS VARCHAR(100)) AS Expr
, T2.value + T1.value AS Value
, T1.ID
, Level + 1
FROM
#TempTable T1
INNER JOIN selfrecCTE T2
ON T1.ID < T2.ID
--WHERE
-- Level < 4 -- limit the number of recursions
)
-- 31 rows. OK.
SELECT * FROM selfrecCTE
ORDER By id, expr, Level
我发现这是一个有趣的消遣。
感谢提问!
SQL 服务器 2008 R2
样本Table结构
create table TempTable
(
ID int identity,
value int
)
insert into TempTable values(6)
insert into TempTable values(7)
insert into TempTable values(8)
insert into TempTable values(9)
insert into TempTable values(10)
我真的想要这样的东西 它 returns 行使得它具有所有剩余行的总和,如下所示。
6+7
6+8
6+9
6+10
6+7+8
6+7+9
6+7+10
6+8+9
6+8+10
6+9+10
6+7+8+9
6+7+8+9+10
AronLS 解决方案满足我的需求。但是,请将问题开放几天。 1. 有 another/better 方法可以做到这一点吗?
这是一个 "all possible permutations" 问题,可以通过自连接和递归 CTE 解决。
With selfrec as (
Select t.Value, t.ID, 0 as Level From TempTable t
UNION ALL
Select t2.Value + t1.Value as Value, t1.ID, Level + 1 From TempTable t1
Inner Join selfrec t2 on t1.ID < t2.ID
Where Level < 4 -- limit the number of recursions
)
Select * From selfrec
Order By Level
此标准消除了与自身匹配的项目,以及排列组合的重复反转:
t1.ID < t2.ID
限制递归的深度,因为我们没有其他突破标准,并且将超过允许的递归数:
Where Level < 4
FWIW-- 稍微点缀一下,就知道是怎么回事了:
CREATE TABLE #TempTable
(
Expr VARCHAR(10),
ID INT IDENTITY,
value INT
)
INSERT INTO #TempTable VALUES('6', 6) -- a
INSERT INTO #TempTable VALUES('7', 7) -- b
INSERT INTO #TempTable VALUES('8', 8) -- c
INSERT INTO #TempTable VALUES('9', 9) -- d
INSERT INTO #TempTable VALUES('10', 10) -- e
SELECT expr, value FROM #TempTable
-- Choose(n,k) = n!/(n!(n-k)!) [order not important]
-- n = 5, k = {1,2,3,4,5}
-- C(5,1) + C(5,2) + C(5,3) + C(5,4) + C(5,5)
-- 5 + 10 + 10 + 5 + 1 = 31
-- There should be 31 rows.
------
;
WITH selfrecCTE AS
(
SELECT
CAST(expr AS VARCHAR(100)) AS Expr
, T.value
, T.ID
, 0 AS Level
FROM
#TempTable AS T
UNION ALL
SELECT
CAST(t1.expr + ' + ' + T2.expr AS VARCHAR(100)) AS Expr
, T2.value + T1.value AS Value
, T1.ID
, Level + 1
FROM
#TempTable T1
INNER JOIN selfrecCTE T2
ON T1.ID < T2.ID
--WHERE
-- Level < 4 -- limit the number of recursions
)
-- 31 rows. OK.
SELECT * FROM selfrecCTE
ORDER By id, expr, Level
我发现这是一个有趣的消遣。 感谢提问!