【问题标题】:Sql - Does the sum of some rows is content between A and B?Sql - 某些行的总和是否是 A 和 B 之间的内容?
【发布时间】:2013-07-08 17:29:23
【问题描述】:

我目前正在尝试查找,如果某些行的总和是 A 和 B 之间的内容。

例如,我需要一个介于 100 平方米和 105 平方米之间的表面, 所以请求应该添加所有行,直到总和在 100 平方米和 105 平方米之间,并尝试所有可能的解决方案。

我有什么

 ________________________________
 | id | id_biens    | surface    |
 |____|_____________|____________|
 |  1 | 001         |   80       |
 |  2 | 001         |   50       |
 |  3 | 001         |   30       |
 |  4 | 001         |   55       |
 |____|_____________|____________|

我想要达到的结果

(50 + 55 = 105) id_biens 001 返回 true。

 ________________________________
 | id | id_biens    | surface    |
 |____|_____________|____________|
 |  2 | 001         |   50       |
 |  4 | 001         |   55       |
 |____|_____________|____________|

感谢您阅读我的帖子!

【问题讨论】:

  • “id_biens”的求和行是否需要具有相同的值?
  • 是的,它需要有相同的 id_biens,2000 行大约有 500 个 id_biens ...
  • 我重写了我的查询以加入 id_biens 并简化它。

标签: sql sum rows cube rollup


【解决方案1】:

一些数据。我添加了一行,以说明重复的表面积。

CREATE TABLE Table1
    (id int, id_biens char(3), surface int)
;

INSERT INTO Table1 VALUES
    (1, '001', 80),
    (2, '001', 50),
    (3, '001', 30),
    (4, '001', 55),
    (5, '001', 50);

这适用于配对。很难将其推广到 SQL 中任意数量的行。这本质上是一个组合问题。您可能需要检查所有可能的行组合,因此在最坏的情况下,您需要生成和评估行集 {1, 2, 3, 4, 12, 13, ... 123, 124... 1234}(例如,在这里使用身份证号)。

对于 1000 行,一次取 4 行可以得到大约 410 亿个组合。统计软件可能是解决此类问题的最佳选择。

我认为,总的来说,以下查询是一种更好的方法。 (但请记住我所说的关于统计软件的内容。)它显着改变了你的输出,但我认为这种改变是更好的。哪些行构成总表面更加清晰。

select distinct b1, 
                id_1, id_2,
                s1, s2,
                (s1 + s2) total_surface
from 
  (select t1.id id_1, t1.id_biens b1, t1.surface s1, 
          t2.id id_2, t2.id_biens b2, t2.surface s2
   from Table1 t1
   inner join Table1 t2
      on t1.id_biens = t2.id_biens
     and t1.id <> t2.id
   where t1.id < t2.id
  ) required_alias
where s1 + s2 between 100 and 105
order by b1, id_1, id_2;

b1   id_1  id_2  s1  s2  total_surface
--
001  2     4     50  55  105
001  2     5     50  50  100
001  4     5     55  50  105

三个值的组合。您需要在 cmets 中进行更改。

select distinct b1, 
                id_1, id_2, id_3,                    -- Add an id,
                 s1,  s2,  s3,                       -- Add a surface
                (s1 + s2 + s3) total_surface         -- Add surface to the total.
from 
  (select t1.id id_1, t1.id_biens b1, t1.surface s1, 
          t2.id id_2, t2.id_biens b2, t2.surface s2,
          t3.id id_3, t3.id_biens b3, t3.surface s3  -- Third of three sets of columns.
   from Table1 t1
   inner join Table1 t2
      on t1.id_biens = t2.id_biens
     and t1.id <> t2.id
   inner join Table1 t3                              -- Additional join.
      on t1.id_biens = t3.id_biens
     and t1.id <> t3.id
   where t1.id < t2.id
     and t2.id < t3.id                               -- Additional restriction
  ) required_alias
where s1 + s2 + s3 between 100 and 105               -- Correct math here, too.

【讨论】:

  • 它工作得很好,除了它正在做 2“表面”的总和,但它应该尝试做 4 的总和,5 “表面”它必须尝试所有组合。有时对于相同的 id_biens 我有 15 个“表面”。我知道尝试所有组合需要时间,但必须完成。非常感谢
  • @TheBigJohn:嗯,我的意思是,似乎需要不同的 SQL 查询来评估每个组合数量。 很难将其推广到 SQL 中任意数量的行。 我认为您最好将数据存储在 SQL 数据库中,并使用应用程序代码对总和进行详尽的枚举,或者做动态规划。
  • 好的,迈克,我想使用不同的 SQL 来评估每个数字组合,但我是 SQL 新手,我不知道如何为表,在我知道如何选择好的行之后。非常感谢
  • @TheBigJohn:更新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 2016-05-04
相关资源
最近更新 更多