Выбрать строку, если хотя бы одна возможная СУММА ее дочерних элементов равна заданному числу?

Я пытаюсь отфильтровать набор квартир, вычисляя каждую возможную поверхность, которую имеет здание, а затем проверяя, соответствует ли она моим критериям или нет.

Пример: у меня есть одно здание А, состоящее из 3 квартир по 200 м² каждая, назовем их 1, 2 и 3.

В моем поиске я должен получить это здание, если мои критерии соответствуют этим данным случаям:

  • Я ищу 200 м² (у нас есть три квартиры, которые соответствуют этим критериям)
  • Я ищу 400 м² (у нас есть несколько возможных СУММ площадей в здании, которые будут совпадать, будь то 1+2, 1+3, 2+3, не имеет значения)
  • Я ищу 600 м² (У нас есть СУММА всех поверхностей здания, 1+2+3)

Я могу ответить на первый случай с помощью MIN(), поэтому я получаю наименьшую доступную поверхность. Я также могу ответить на последний случай, потому что я получаю максимально возможную доступную поверхность с SUM() всех квартир.

Но меня беспокоит второй случай, я не знаю, смогу ли я вычислить эти «Возможные СУММЫ», как я бы их назвал, внутри запроса.

Вот SQL, который у меня есть до сих пор, хорошо зная, что он не отвечает на второй случай:

SELECT DISTINCT building.* 
FROM building AS building   
    LEFT JOIN appartment a ON a.id_building = building.id 
WHERE (
        SELECT MIN(a2.surface) 
        FROM appartment a2 
            INNER JOIN building ON a2.id_building= building.id 
      ) >= 399
AND (
        SELECT SUM(a2.surface) 
        FROM appartment a2 
            INNER JOIN building ON lot.id_building= building.id 
    ) <= 401

Я пытался работать со всем набором результатов с PHP, а не с SQL, но это не мой предпочтительный вариант, потому что это означало бы переделку большого количества работы, которую я не делал, поэтому это быстро усложнялось. Я также читал об утверждениях HAVING, но я не понимаю, куда я должен их поместить и каким должно быть условие внутри.

Каково потенциальное максимальное количество квартир в доме? Сколько из них можно сложить вместе, чтобы соответствовать вашему критерию поверхности. Может ли быть в наличии здание со 100 квартирами и запрос на поиск общей площади 2000 (8*200 + 1*180 + 1*220)? Возможно, но нецелесообразно решать это с помощью SQL.

nnichols 16.11.2022 17:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
1
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

может быть что-то вроде этого, но я не очень уверен в вашей структуре таблицы

    SET @totalSurface= 0;
    SELECT @totalSurface:=@totalSurface+`surface`, `id`, `building` FROM `apartment`
    WHERE @totalSurface=400
    GROUP BY `building` ;

Разве это не эквивалентно "ГДЕ (ВЫБЕРИТЕ СУММУ(поверхность) ИЗ квартиры = 400)? У меня проблемы с пониманием оператора :=@

Nico 16.11.2022 11:17

В MySQL := — это оператор присваивания. Заставляет пользовательскую переменную слева от оператора принимать значение справа. Что происходит, когда вы запускаете запрос? это результат желания?

benkov 16.11.2022 12:03

К сожалению, нет, это не дает мне никакого результата, когда я запускаю его. Я знаю, что он должен получить мой пример конкретно.

Nico 16.11.2022 14:09
Ответ принят как подходящий

Наконец-то мне удалось найти что-то, используя хранимую функцию. Я использую этот курсор с идентификатором здания в качестве параметра для перебора всех квартир указанного здания, отсортированных по поверхности. Затем для каждого цикла я добавляю поверхность к своей сумме и проверяю, нахожусь ли я в своем интервале заданных критериев. Если да, установите для возвращаемого значения значение true, если нет, возвращаемое значение остается ложным.

Вот оно, я надеюсь, что это поможет, если кто-то застрял, как я:

CREATE DEFINER=`homestead`@`%` FUNCTION `buildingHasSurface`(`surface_min` INT, `surface_max` INT, `building_id` INT) RETURNS TINYINT(1)
BEGIN
  DECLARE curseurFini INT;
  DECLARE valide INT;

  DECLARE surface_totale INT;
  DECLARE surface_row INT;

  DECLARE curs CURSOR FOR SELECT surface_dispo FROM appartement WHERE id_building = building_id ORDER BY surface_dispo ASC;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET curseurFini = 1;

  OPEN curs;

  SET curseurFini = 0;
  SET surface_totale = 0;
  SET valide = 0;
  
  REPEAT
    FETCH curs INTO surface_row;
      IF curseurFini = 0 THEN
        SET surface_totale = surface_totale + surface_row;
        IF surface_totale >= surface_min 
        AND surface_totale <= surface_max
        THEN 
        SET valide = 1;
      END IF;
    END IF;
  UNTIL curseurFini END REPEAT;

  CLOSE curs;





  RETURN valide;
END$$

Другие вопросы по теме