как рассчитать процент mysql оконная функция - PullRequest
2 голосов
/ 27 февраля 2020

поэтому у меня есть структура таблицы, подобная этой

CREATE TABLE sales(
    id_order VARCHAR(50) NOT NULL,
    fiscal_year INT NOT NULL,
    sale DECIMAL(14,2) NOT NULL,
    location varchar(50) NOT NULL,
    PRIMARY KEY(id_order,fiscal_year)
);

INSERT INTO sales(id_order,fiscal_year,sale, location)
VALUES(1,2016,100, 'Jakarta'),
      (2,2017,150, 'Bekasi'),
      (3,2018,200, 'Depok'),
      (4,2016,150, 'Jakarta'),
      (5,2017,100, 'Bekasi'),
      (6,2018,200, 'Depok'),
       (7,2016,200, 'Jakarta'),
      (8,2017,150, 'Bekasi'),
      (9,2018,250, 'Depok');

SELECT * FROM sales;

в этом случае, я хочу сделать процент от суммы продажи и количества id_order для местоположения

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

+----------+-----------+-----------+--------------------+----------------------+
| Location |  sale(kg) |  sale (%) |   count(id_order)  |  count(id_order) (%) |
+----------+-----------+-----------+--------------------+----------------------+
| Jakarta  |       450 | 30 %      |                  3 | 33,33%               |
| Bekasi   |       400 | 26,67 %   |                  3 | 33,33%               |
| Depok    |       650 | 43,33 %   |                  3 | 33,33%               |
| Total    |      1500 | 100 %     |                  9 | 100%                 |
+----------+-----------+-----------+--------------------+----------------------+

я пробовал с этим синтаксисом

SELECT 
    location,
    sum(sale)/ sum(sale) over()
    sum(count(id_order)) / sum(count(id_order)) over()
FROM
    sales
    group by location; 

, но сказано, что выражение # 2 списка SELECT отсутствует в предложении GROUP BY и содержит неагрегированные столбец 'fiddle_WKQHEMOVYSDKFWLXWXHB.sales.sale', который функционально не зависит от столбцов в предложении GROUP BY; это несовместимо с sql_mode = only_full_group_by

ПРОВЕРЬТЕ ДЕМО ЗДЕСЬ

Ответы [ 2 ]

2 голосов
/ 27 февраля 2020

Вы можете использовать следующее решение, используя SUM .. OVER:

SELECT DISTINCT 
  location AS `Location`, 
  SUM(sale) OVER (PARTITION BY location) AS `sale(kg)`,
  SUM(sale) OVER (PARTITION BY location) / SUM(sale) OVER () * 100 AS `sale (%)`,
  COUNT(id_order) OVER (PARTITION BY location) AS `count(id_order)`,
  COUNT(id_order) OVER (PARTITION BY location) / COUNT(id_order) OVER () * 100 AS `count(id_order) (%)`
FROM sales
UNION ALL
SELECT 'Total', SUM(sale), 100, COUNT(id_order), 100
FROM sales

... или вы можете использовать следующее решение, используя GROUP BY с WITH ROLLUP :

SELECT 
  IFNULL(location, 'Total') AS `Location`, 
  SUM(sale) AS `sale(kg)`,
  SUM(sale) / (SELECT SUM(sale) FROM sales) * 100 AS `sale (%)`, 
  COUNT(id_order) AS `count(id_order)`,
  COUNT(id_order) / (SELECT COUNT(id_order) FROM sales) * 100 AS `count(id_order) (%)`
FROM sales 
GROUP BY location WITH ROLLUP;

демо на dbfiddle.uk

1 голос
/ 27 февраля 2020
WITH cte AS ( SELECT location,
                     sum(sale) sale,
                     count(id_order) cnt
              FROM sales
              group by location with rollup )
SELECT COALESCE(t1.location, 'TOTAL') location,
       t1.sale `sale (kg)`,
       t1.sale / t2.sale * 100 `sale (%)`,
       t1.cnt `count(id_order)`,
       t1.cnt / t2.cnt * 100 `count(id_order) (%)`
FROM cte t1, cte t2
WHERE t2.location is null

скрипка

...