Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Применение оператора SUM() для суммирования по нескольким разным промежуткам. / 7 сообщений из 7, страница 1 из 1
08.03.2018, 22:53
    #39612365
Hofmann
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
Есть, например, такая таблица Table:

id Class Qty1A42B63C94A125B86C207A18B59C13
Я хочу просуммировать столбец Qty по разным промежуткам id сгруппировав их по столбцу Class.
Исходя из таблицы выше, мне нужно получить следующую таблицу:

ClassSumQty1SumQty2SumQty3A1610B685C92013
где
SumQty1 - сумма по Qty с условие того, что 1 <= id <= 4,
SumQty2 - сумма по Qty с условие того, что 5 <= id <= 7,
SumQty3 - сумма по Qty с условие того, что 8 <= id <= 9.
Хочу обратить внимание, что промежутки разной длины.

Я сделал это с использованием подзапросов следующий образом:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
SELECT
     ClassX AS Class 
     Qty1, 
     Qty2, 
     Qty3
FROM 
     (SELECT
          Class AS ClassX
          SUM(Qty) AS SumQty1
      FROM
          Table
      WHERE id BETWEEN 1 AND 4
      GROUP BY Class) AS X
JOIN
     (SELECT
          Class AS ClassY
          SUM(Qty) AS SumQty2
      FROM
          Table
      WHERE id BETWEEN 5 AND 7
      GROUP BY Class) AS Y
ON X.ClassX = Y.ClassY
JOIN
     (SELECT
          Class AS ClassZ
          SUM(Qty) AS SumQty3
      FROM
          Table
      WHERE id BETWEEN 8 AND 9
      GROUP BY Class) AS Z
ON Y.ClassY = Z.ClassZ
ORDER BY Class


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

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

То есть, в общем, меня интересует можно ли как-то уменьшить скорость выполнения такого запроса.
...
Рейтинг: 0 / 0
08.03.2018, 23:05
    #39612366
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
Навскидку так примерно
Код: sql
1.
2.
3.
4.
5.
6.
SELECT
    COUNT(`id` BETWEEN 1 AND 4) AS `SumQty1`,
    COUNT(`id` BETWEEN 5 AND 7) AS `SumQty2`,
    COUNT(`id` BETWEEN 8 AND 9) AS `SumQty3`
FROM `Table`
GROUP BY `Class`
...
Рейтинг: 0 / 0
08.03.2018, 23:14
    #39612370
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
Прошу пардону, NULLIF забыл воткнуть. Так:

Код: sql
1.
    COUNT(NULLIF(`id` BETWEEN 1 AND 4, 0)) AS `SumQty1`,
...
Рейтинг: 0 / 0
08.03.2018, 23:21
    #39612372
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
Глупость выше написал, Вам же сумма нужна, а не количество.
...
Рейтинг: 0 / 0
08.03.2018, 23:36
    #39612376
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
Ну, смысл тот же
Код: sql
1.
2.
3.
4.
5.
6.
SELECT
    SUM(IF(`id` BETWEEN 1 AND 4, `Qty`, 0)) AS `SumQty1`,
    SUM(IF(`id` BETWEEN 5 AND 7, `Qty`, 0)) AS `SumQty2`,
    SUM(IF(`id` BETWEEN 8 AND 9, `Qty`, 0)) AS `SumQty3`
FROM `Table`
GROUP BY `Class`
...
Рейтинг: 0 / 0
09.03.2018, 00:50
    #39612391
Hofmann
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
vkle,

Спасибо большое за Ваш вариант. Я пробовал написать что-то похожее, только с оператором CASE и это выглядело так:

Код: plsql
1.
2.
3.
4.
5.
6.
SELECT
    SUM(CASE WHEN `id` BETWEEN 1 AND 4 THEN `Qty` ELSE 0 END) AS `SumQty1`,
    SUM(CASE WHEN `id` BETWEEN 5 AND 7 THEN `Qty` ELSE 0 END) AS `SumQty2`,
    SUM(CASE WHEN `id` BETWEEN 8 AND 9 THEN `Qty` ELSE 0 END) AS `SumQty3`
FROM `Table`
GROUP BY `Class`



Что в принципе аналогично IF, как мне кажется. Но у меня всё равно возникает вопрос. Разве каждый оператор SUM() не проходится отдельно по таблице? То есть для первого оператора SUM() ищутся совпадения по всей таблице по условию IF или CASE, потом тоже самое по второму и третьему операторам.
...
Рейтинг: 0 / 0
09.03.2018, 05:26
    #39612415
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Применение оператора SUM() для суммирования по нескольким разным промежуткам.
HofmannЧто в принципе аналогично IF, как мне кажется.Кажется, в общем, правильно. С алгоритмической точки зрения оператор ветвления if...else является базовым, его можно использовать при написании более сложных конструкций, таких как case. В данном случае в case проверяется лишь одно условие, а значит, и при развертывании алгоритма там будет использован лишь один if...else. В некотором смысле case тут избыточен. :)

HofmannРазве каждый оператор SUM() не проходится отдельно по таблице?Из таблицы извлекается и обрабатывается строка, где поля id и Qty присутствуют и, следовательно, их значения могут быть использованы где угодно. В данном случае значения используются в трех выражениях.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Применение оператора SUM() для суммирования по нескольким разным промежуткам. / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]