MySQL, как выбрать 1, если MAX () равен текущему совокупному значению SUM () строки? - PullRequest
3 голосов
/ 11 октября 2011

Я бы хотел выбрать новый столбец с именем sliced (значение может быть 1/0 или true/false, это не имеет значения), если area текущей строки равно MAX(SUM(c.area)), то есть flag строка с наибольшим совокупным значением:

SELECT p.name AS name, SUM(c.area) AS area
FROM City AS c
   INNER JOIN Province AS p ON c.province_id = p.id
      INNER JOIN Region AS r ON p.region_id = r.id
WHERE r.id = ?
GROUP BY p.id
ORDER BY p.name ASC

Я пытался добавить к выбору area = MAX(area) AS sliced или даже area = SUM(MAX(c.area)) AS sliced, но получаю синтаксическую ошибку.Я должен признать, что я не так хорош в SQL.Спасибо.

Ответы [ 3 ]

2 голосов
/ 11 октября 2011

Как я понимаю ваш вопрос, это должно сделать это.Создает псевдостолбец, который возвращает 1, когда область совпадает с max (area) без каких-либо условий, чтобы ограничить ваш выбор.не выполнять вложенное агрегирование, поэтому sum(max(area)) не будет работать, и вам нужно будет выполнять эти операции по одному запросу за раз.

1 голос
/ 11 октября 2011

Вот способ сделать это только с одной группой:

set @row := 0;
select name, area, sliced
from (
    select name, area, (@row := @row + 1) = 1 as sliced
    from (
        SELECT p.name, SUM(c.area) AS area
        FROM City AS c
        INNER JOIN Province AS p ON c.province_id = p.id
        INNER JOIN Region AS r ON p.region_id = r.id
        WHERE r.id = ?
        GROUP BY 1
        ORDER BY 2 desc) t1
    ) t2
order by 1;

Внутренний запрос (t1) сначала группирует и сортирует по общей площади.
Следующий запрос (t2) дает первой строке значение true для столбца sliced, все остальные строки false.
Внешний запрос упорядочивает строки так, как вы хотите - по имени.

Поскольку существует только одна таблица сканирования и группировки, это должно быть очень эффективно.

0 голосов
/ 11 октября 2011

Как уже упоминалось в комментариях, вам нужно будет проверить все значения по другому запросу. Это нормальная практика в SQL.

SELECT
  p.name AS name,
  SUM(c.area) AS area,
  CASE WHEN SUM(c.area) = (SELECT MAX(area) FROM <repeat your query here>) THEN 1 ELSE 0 END
FROM
  City     AS c
INNER JOIN
  Province AS p
    ON c.province_id = p.id
INNER JOIN
  Region   AS r
    ON p.region_id = r.id
WHERE
  r.id = ?
GROUP BY
  p.id
ORDER BY
  p.name ASC

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

Альтернативой является вставка всех данных во временную таблицу с полем среза, равным 0 для всех записей. Затем обновите эту таблицу, установив срез на 1 для записи (записей) с самой высокой площадью.

...