Sql - сгруппировать по диапазону (м2) и суммировать цены элементов в диапазоне - PullRequest
0 голосов
/ 12 июня 2018

Я sql новичок, и я не знаю, как продолжить этот запрос.

У меня есть эта таблица m2AndPrices.Он содержит активы и их поверхность, а также связанные с ними значения.

|---------------------------------------------|
|id     |     code      |   m2   |      value |
|---------------------------------------------|
|32980  | 143452asd10   | 11.17  |      0     |
|---------------------------------------------|
|25107  | 20152fgg219   | 57.00  |   55304,99 |
|---------------------------------------------|
|5692   | 203hhh75735   | 87.18  |   98334,16 |
|---------------------------------------------|
|31500  | 200788fgfg193 | 240.64 |  164401,75 |
|---------------------------------------------|

Группировка по квадратным метрам (м2) и выполнение подсчета Я получаю этот вывод:

|----------------------------------|
|m2section |     number_of_assets  |
|----------------------------------|
|<1        |         175           |
|----------------------------------|
|1-5       |         286           |
|----------------------------------|
|5-10      |         374           |
|----------------------------------|
|10-20     |         573           |  
|----------------------------------|
|20-40     |        5212           |
|----------------------------------|
|40-80     |        3892           |
|----------------------------------|
|80-120    |        4121           |
|----------------------------------|
|120-180   |        1849           |
|----------------------------------|
|180-250   |         705           |
|----------------------------------|
|250-500   |         430           |
|----------------------------------|
| >500     |         131           |
|----------------------------------|

Код:

    SELECT * FROM (
    SELECT cast(m2section as varchar), COUNT(*) as number_of_assets FROM (
    SELECT 
    CASE 
        WHEN m2 <= 1 THEN '<1'
        WHEN m2 > 1 AND m2 <= 5 THEN '1-5'
        WHEN m2 > 5 AND m2 <= 10 THEN '5-10' 
        WHEN m2 > 10 AND m2 <= 20 THEN '10-20'
        WHEN m2 > 20 AND m2 <= 40 THEN '20-40'
        WHEN m2 > 40 AND m2 <= 80 THEN '40-80'
        WHEN m2 > 80 AND m2 <= 120 THEN '80-120'
        WHEN m2 > 120 AND m2 <= 180 THEN '120-180'
        WHEN m2 > 180 AND m2 <= 250 THEN '180-250'
        WHEN m2 > 250 AND m2 <= 500 THEN '250-500'
        WHEN m2 > 500 THEN '>500' END AS m2section  
FROM (select * from m2AndPrices x) as a
) as A 
GROUP BY m2section) as B
order by CASE
    WHEN m2section = '<1' THEN 1
    WHEN m2section = '1-5' THEN 2
    WHEN m2section = '5-10'  THEN 3 
    WHEN m2section = '10-20' THEN 4
    WHEN m2section = '20-40' THEN 5
    WHEN m2section = '40-80' THEN 6
    WHEN m2section = '80-120' THEN 7
    WHEN m2section = '120-180' THEN 8
    WHEN m2section = '180-250' THEN 9
    WHEN m2section = '250-500' THEN 10
    WHEN m2section = '>500' THEN 11
END
;

Извините, если он не имеет хорошего отступа.

Мне нужно получить другой столбец, который подсчитывает значение количества элементов в каждом диапазоне, например:

|------------------------------------------------------|
|m2section |     number_of_assets  |  total value ($)
|------------------------------------------------------|
|<1        |         175           |    345.436
|------------------------------------------------------|
|1-5       |         286           |    864.364
|------------------------------------------------------|
|5-10      |         374           |   364.334
|------------------------------------------------------|
|10-20     |         573           |  1.364.364 
|------------------------------------------------------|
|20-40     |        5212           |  8.364.364
|------------------------------------------------------|
|40-80     |        3892           |  6.364.364
|------------------------------------------------------|
|80-120    |        4121           |     .....
|------------------------------------------------------|
|120-180   |        1849           |     .....
|------------------------------------------------------|
|180-250   |         705           |     .....
|------------------------------------------------------|
|250-500   |         430           |     .....
|------------------------------------------------------|
| >500     |         131           |     .....
|------------------------------------------------------|

Но я не знаю, где я могу сделать подсчет значения ($).

Любая идея будет оценена.

Большое спасибо

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

В Postgres я бы порекомендовал:

SELECT (CASE WHEN m2 <= 1 THEN '<1'
             WHEN m2 > 1 AND m2 <= 5 THEN '1-5'
             WHEN m2 > 5 AND m2 <= 10 THEN '5-10' 
             WHEN m2 > 10 AND m2 <= 20 THEN '10-20'
             WHEN m2 > 20 AND m2 <= 40 THEN '20-40'
             WHEN m2 > 40 AND m2 <= 80 THEN '40-80'
             WHEN m2 > 80 AND m2 <= 120 THEN '80-120'
             WHEN m2 > 120 AND m2 <= 180 THEN '120-180'
             WHEN m2 > 180 AND m2 <= 250 THEN '180-250'
             WHEN m2 > 250 AND m2 <= 500 THEN '250-500'
             WHEN m2 > 500 THEN '>500'
        END) AS m2section,
       COUNT(*) as num_assets,
       SUM(value) as sum_value 
FROM m2AndPrices mp
GROUP BY m2section
ORDER BY MIN(m2);

Теперь я бы также упростил выражение CASE:

SELECT (CASE WHEN m2 <= 1 THEN '<1'
             WHEN m2 <= 5 THEN '1-5'
             WHEN m2 <= 10 THEN '5-10' 
             WHEN m2 <= 20 THEN '10-20'
             WHEN m2 <= 40 THEN '20-40'
             WHEN m2 <= 80 THEN '40-80'
             WHEN m2 <= 120 THEN '80-120'
             WHEN m2 <= 180 THEN '120-180'
             WHEN m2 <= 250 THEN '180-250'
             WHEN m2 <= 500 THEN '250-500'
             WHEN m2 > 500 THEN '>500'
        END) AS m2section,
       COUNT(*) as num_assets,
       SUM(value) as sum_value 
FROM m2AndPrices mp
GROUP BY m2section
ORDER BY MIN(m2);

Примечания:

  • * Выражения 1011 * вычисляются по порядку (гарантировано), поэтому вам не нужны выражения AND.
  • Вы можете использовать псевдонимы столбцов в GROUP BY.Настоятельно рекомендуется использовать псевдонимы столбцов над номерами столбцов, поскольку последние не рекомендуется использовать в самой последней версии стандарта SQL.
  • ORDER BY немного хитр, но упорядочит по m2значения, что вы действительно хотите.
  • Я предполагаю, что каждая строка в исходной таблице представляет актив, без дубликатов, поэтому COUNT(*) подходит.Если у вас могут быть дубликаты, то вам нужно COUNT(DISTINCT), но DISTINCT требует накладных расходов, поэтому не используйте его, если в этом нет необходимости.
0 голосов
/ 12 июня 2018

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

Сначала вы хотите классифицировать по м2, верно?

SELECT 
  CASE
    WHEN m2 <= 1 THEN '<1'
    WHEN m2 > 1 AND m2 <= 5 THEN '1-5'
    WHEN m2 > 5 AND m2 <= 10 THEN '5-10' 
    WHEN m2 > 10 AND m2 <= 20 THEN '10-20'
    WHEN m2 > 20 AND m2 <= 40 THEN '20-40'
    WHEN m2 > 40 AND m2 <= 80 THEN '40-80'
    WHEN m2 > 80 AND m2 <= 120 THEN '80-120'
    WHEN m2 > 120 AND m2 <= 180 THEN '120-180'
    WHEN m2 > 180 AND m2 <= 250 THEN '180-250'
    WHEN m2 > 250 AND m2 <= 500 THEN '250-500'
    WHEN m2 > 500 THEN '>500' 
  END AS m2section
  FROM m2AndPrices
  GROUP BY 1 -- you can group by giving the index of the columns in the SELECT statement  

Это отправная точка.Теперь, если вы хотите рассчитать количество строк, вы используете COUNT.В целях безопасности рекомендуется использовать COUNT (идентификатор DISTINCT), чтобы любые дубликаты не учитывались дважды.В вашем случае это будет COUNT (DISTINCT id) для подсчета количества продаж или чего-либо еще в вашей таблице

Когда вы хотите получить общую стоимость, вы используете SUM.Таким образом, вы должны сделать SUM (total_value)

Полный код:

SELECT 
  CASE
    WHEN m2 <= 1 THEN '<1'
    WHEN m2 > 1 AND m2 <= 5 THEN '1-5'
    WHEN m2 > 5 AND m2 <= 10 THEN '5-10' 
    WHEN m2 > 10 AND m2 <= 20 THEN '10-20'
    WHEN m2 > 20 AND m2 <= 40 THEN '20-40'
    WHEN m2 > 40 AND m2 <= 80 THEN '40-80'
    WHEN m2 > 80 AND m2 <= 120 THEN '80-120'
    WHEN m2 > 120 AND m2 <= 180 THEN '120-180'
    WHEN m2 > 180 AND m2 <= 250 THEN '180-250'
    WHEN m2 > 250 AND m2 <= 500 THEN '250-500'
    WHEN m2 > 500 THEN '>500' 
  END AS m2section,
  COUNT(DISTINCT id) AS number_of_assets_per_m2_band,
  SUM(total_value) AS total_value_per_m2_band
  FROM m2AndPrices
  GROUP BY 1 -- you can group by giving the index of the columns in the SELECT statement 
  ORDER BY 1 DESC;
...