how to calculate percentage mysql window function

Fachry Dzaky Al-Qadri Sabil :

so i have table structure like this

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;

on this case, i want to make a percentage for the amount of sale and count of id_order over location

based on my case, this is the expected results :

+----------+-----------+-----------+--------------------+----------------------+
| 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%                 |
+----------+-----------+-----------+--------------------+----------------------+

i've try with this syntax

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

but it's said Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'fiddle_WKQHEMOVYSDKFWLXWXHB.sales.sale' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

CHECK DEMO HERE

Sebastian Brosch :

You can use the following solution using 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

... or you can use the following solution using GROUP BY with 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;

demo on dbfiddle.uk

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=10119&siteId=1