根据SQL数据库的一些计算,我有一张表,它看起来像这样:
[ID] [PAR1] [PAR2]
[A] [110] [0.5]
[B] [105] [1.5]
[C] [120] [2.0]
[D] [130] [3.0]
[E] [115] [5.5]
[F] [130] [6.5]
[G] [120] [7.0]
[H] [110] [7.5]
[I] [105] [8.0]
[J] [120] [9.0]
[K] [110] [9.5]
按PAR2排序-更少意味着更好的结果。 我需要从3行中找到 SUM PAR2的最佳结果,其中PAR1的总和至少为350(至少为350)。例如:
这是一个ASP.NET应用程序,因此我尝试从数据库中获取表并在后面使用VB代码来获取结果,但这是使用FOR..NEXT LOOP
的“手动”工作,需要花费一些时间。因此,对于这样的计算而言,这不是一个很好的选择,而且也太慢了。
我想知道是否有更好的平滑智能SQL代码可以直接从SQL Query获取结果。也许一些高级数学功能?有什么想法吗?
预先感谢。
我使用forpas解决方案进行了一些测试,是的,它的效果非常好。但是当我添加很多WHERE条件时需要花费很多时间,因为原始表非常大。因此,我将尝试找到在函数(而非过程)中使用临时表的解决方案。谢谢大家的答案。
forpas,特别感谢您提供示例和解释,通过这种方式,您可以让我快速地了解您的想法-这是大师级别;)
答案 0 :(得分:1)
您可以像这样使用双重内部自联接:
select top 1 * from tablename t1
inner join tablename t2 on t2.id > t1.id
inner join tablename t3 on t3.id > t2.id
where t1.par1 + t2.par1 + t3.par1 >= 350
order by t1.par2 + t2.par2 + t3.par2
请参见demo。
结果:
> ID | PAR1 | PAR2 | ID | PAR1 | PAR2 | ID | PAR1 | PAR2
> :- | ---: | :--- | :- | ---: | :--- | :- | ---: | :---
> A | 110 | 0.5 | C | 120 | 2.0 | D | 130 | 3.0
所以获胜者是 A + C + D ,因为:
110 + 120 + 130 = 360 >= 350
并且PAR2的总和是
0.5 + 2.0 + 3.0 = 5.5
这是最小值
答案 1 :(得分:0)
检查此。我觉得它准确或接近您的要求-
WITH CTE (ID,PAR1,PAR2)
AS
(
SELECT 'A',110,0.5 UNION ALL
SELECT 'B',105,1.5 UNION ALL
SELECT 'C',120,2.0 UNION ALL
SELECT 'D',130,3.0 UNION ALL
SELECT 'E',115,5.5 UNION ALL
SELECT 'F',130,6.5 UNION ALL
SELECT 'G',120,7.0 UNION ALL
SELECT 'H',110,7.5 UNION ALL
SELECT 'I',105,8.0 UNION ALL
SELECT 'J',120,9.0 UNION ALL
SELECT 'K',110,9.5
)
SELECT B.AID,B.BID,B.CID,SUM_P2,SUM_P1
(
SELECT * , ROW_NUMBER() OVER (PARTITION BY CHAR_SUM ORDER BY CHAR_SUM) CS
FROM
(
SELECT ASCII(A.ID) + ASCII(B.ID)+ASCII(C.ID) CHAR_SUM,
A.ID AID,B.ID BID,C.ID CID,
(A.PAR2+B.PAR2+C.PAR2) AS SUM_P2,
(A.PAR1+B.PAR1+C.PAR1) AS SUM_P1
FROM CTE A
CROSS APPLY CTE B
CROSS APPLY CTE C
WHERE A.ID <> B.ID AND A.ID <> C.ID AND B.ID <> C.ID
AND (A.PAR1+B.PAR1+C.PAR1) >= 350
) A
)B
WHERE CS = 1
答案 2 :(得分:0)
您可以尝试将表自身交叉连接三遍。这样,您就可以将三行的所有组合都旋转到单行上,从而使您能够应用所需的条件并选择最大值。
select t1.ID, t2.ID, t3.ID, t1.PAR2 + t2.PAR2 + t3.PAR2
from yourTable t1
cross join
yourTable t2
cross join
yourTable t3
where t1.ID < t2.ID and t2.ID < t3.ID and
t1.PAR1 + t2.PAR1 + t3.PAR1 >= 350
order by t1.PAR2 + t2.PAR2 + t3.PAR2 ASC
虽然此解决方案在技术上应该可行,但是交叉连接表并不是理想的性能,甚至多次执行时也是如此。如果表的大小将随着时间增长,并且您可以选择在代码级应用计算,我认为这样做是明智的。
修改
更改了where
子句,包括塞尔格的建议