You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选存在子项组合面积和等于指定值的建筑?

解决建筑公寓面积组合和的SQL筛选问题

要实现任意数量公寓面积组合和的筛选,仅靠MIN()和SUM()只能覆盖单套和总面积的情况,中间的组合需要用**递归CTE(公共表表达式)**来生成所有可能的子集和,再匹配目标条件。

原SQL的问题

你的现有SQL存在两处明显问题:

  • 子查询中表别名错误:lot.id_building应该是a2.id_building
  • 仅覆盖了单套最小面积和总面积,完全没处理中间的组合和场景

解决方案:递归CTE生成所有组合和

以下是针对目标范围(比如399-401㎡)的完整SQL,会自动生成每个建筑下所有可能的公寓面积组合和,再筛选符合条件的建筑:

WITH RECURSIVE apartment_sums AS (
    -- 初始步骤:单套公寓的面积
    SELECT 
        a.id_building,
        a.surface AS total_surface,
        CAST(a.id AS VARCHAR) AS used_apartments -- 记录已选公寓ID,避免重复组合
    FROM appartment a

    UNION ALL

    -- 递归步骤:累加其他未选的公寓面积
    SELECT 
        s.id_building,
        s.total_surface + a.surface AS total_surface,
        s.used_apartments || ',' || a.id AS used_apartments
    FROM apartment_sums s
    JOIN appartment a 
        ON a.id_building = s.id_building 
        AND a.id > (SELECT MAX(CAST(unnest(string_to_array(s.used_apartments, ',')) AS INT))) -- 确保只加未选过的公寓,避免重复组合
)
SELECT DISTINCT b.*
FROM building b
WHERE EXISTS (
    SELECT 1
    FROM apartment_sums s
    WHERE s.id_building = b.id
      AND s.total_surface BETWEEN 399 AND 401 -- 匹配目标面积范围
);

代码解释

  1. 递归CTE的初始部分:先取出每个公寓的单套面积,作为基础组合。
  2. 递归部分:不断将已有组合和与同建筑下未被选中的公寓面积累加,生成新的组合和,同时记录已用公寓ID防止重复计算(比如避免把“公寓1+公寓2”和“公寓2+公寓1”当成两个不同组合)。
  3. 最终筛选:通过EXISTS判断该建筑是否存在符合目标范围的组合和,返回对应的建筑信息。

适配你的示例场景

如果建筑A有3套200㎡的公寓,递归CTE会生成以下组合和:

  • 200(单套)
  • 400(任意两套之和)
  • 600(三套总和)
    当目标范围是399-401时,就会匹配到400㎡的组合,从而检索到该建筑。

注意事项

  • 如果公寓数量较多,递归可能会产生大量数据,建议在实际使用时添加建筑ID的过滤条件减少计算量。
  • 不同数据库的字符串处理函数可能有差异(比如PostgreSQL用string_to_array,MySQL用SUBSTRING_INDEX),需要根据你使用的数据库调整递归部分的ID判断逻辑。

内容的提问来源于stack exchange,提问作者Nico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:05:31