Как рассчитать процент на основе нескольких условий mysql из другой таблицы - PullRequest
0 голосов
/ 04 марта 2020

У меня есть 2 такие таблицы с sales.id_Location = location.id_location (это не реальные данные, только фиктивные данные) в таблице продаж, id_order - история транзакций, созданная на дату транзакции, продажа - сумма транзакции (кг), id_Location - это место доставки, которое связано с id_location в таблице местоположений, созданное покупателем.

CREATE TABLE sales
(
    id_order VARCHAR(50) NOT NULL,
    createdAt datetime NOT NULL,
    sale DECIMAL(14,2) NOT NULL,
    id_location varchar(50) NOT NULL,
    createdby varchar(50) NOT NULL,
    PRIMARY KEY(id_order,createdAt)
);

INSERT INTO sales (id_order, createdAt, sale, id_location, createdby)
VALUES(1,'2016-02-02',100, 1, 123),
      (2,'2017-03-02',150, 2, 233),
      (3,'2018-02-02',200, 3, 234),
      (4,'2016-03-03',150, 1, 123),
      (5,'2017-03-04',100, 2, 2334),
      (6,'2018-03-05',200,3, 234),
       (7,'2016-03-10',200, 1, 233),
      (8,'2017-02-01',150, 2, 124),
      (9,'2018-02-04',250, 3, 233),
      (10,'2018-02-05',300, 2, 124);

CREATE TABLE location
(
     id_location varchar(50) NOT NULL,
     location_city varchar(50) NOT NULL
);

INSERT INTO location(id_location, location_city)
VALUES (1, 'Jakarta'),
 (2, 'Depok'),
 (3, 'Bekasi');

select * from sales;
select * from location;

Это скрипка https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=eac3dc2845bfa425fbd576cc18c72609

В этом случае я использовал mysql версию 5.7, я хочу узнать статистику c продаж для каждого местоположения с этим условием

  1. продажи между 2016-02-01 'до' 2018-03-10 '

  2. покупатели (столбец createdby) совершают транзакцию до' 2018-03-10 'и, по крайней мере, совершают транзакцию снова между '2016-02-01' - '2018-03-10',

Так что, если покупатели просто совершают транзакцию один раз или делают транзакцию более одного раза, но между транзакциями вообще нет транзакций «2016-02-01» до «2018-03-10», тогда покупатели не учитываются и не включаются

Исходя из этого условия и на основе фиктивных данных, ожидаемые результаты будут такими:

+----------+----------+---------+----------------+--------------------+
| Location | sale(kg) | sale(%) | count id_order | count id_order (%) |
+----------+----------+---------+----------------+--------------------+
| Jakarta  |      450 |   26,48 |              3 |              33,33 |
| Depok    |      600 |   35,30 |              3 |              33,33 |
| Bekasi   |      650 |   38,22 |              3 |              33,33 |
| TOtal    |     1700 |     100 |              9 |                100 |
+----------+----------+---------+----------------+--------------------+

Это мое SQL утверждение:

SELECT 
  IFNULL(location.location_city, '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, location
where sales.id_location = location.id_location
and createdAt <= '2018-03-04'
and EXISTS (select 1 from sales s2, location l2 where
sales.id_location = s2.id_location
and sales.id_location = l2.id_location and
createdAt >= '2016-02-01'
and createdAt <= '2018-03-04')
GROUP BY location WITH ROLLUP
having count(createdby) > 1;

Это скрипка https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=eac3dc2845bfa425fbd576cc18c72609

1 Ответ

1 голос
/ 04 марта 2020

Тест

SELECT COALESCE(location_city, 'Total') AS `Location`, 
       SUM(sale) AS `sale(kg)`,
       SUM(sale) / ANY_VALUE(totalsum) * 100 AS `sale (%)`, 
       COUNT(id_order) AS `count(id_order)`,
       COUNT(id_order) / ANY_VALUE(totalcount) * 100 AS `count(id_order) (%)`
FROM sales
NATURAL JOIN location
NATURAL JOIN ( SELECT s1.createdby
               FROM sales s1
               GROUP BY s1.createdby
               HAVING SUM(s1.createdAt BETWEEN '2016-02-01' AND '2018-03-04')
                  AND SUM(s1.createdAt <= '2018-03-04') > 1 ) clients
JOIN ( SELECT SUM(sale) totalsum, 
              COUNT(id_order) totalcount 
       FROM sales ) totals
GROUP BY location_city WITH ROLLUP

скрипка (см. Комментарии в скрипке).


общая сумма в процентах в продаже и число id_order должно быть 100, потому что это подсчитывает общую статистику c для диапазона дат, а не для общих данных в фиктивных данных - Fachry Dzaky

В этом случае эти общие значения должны рассчитываться отдельно. Тест

SELECT COALESCE(location_city, 'Total') AS `Location`, 
       SUM(sale) AS `sale(kg)`,
       SUM(sale) / ANY_VALUE(totalsum) * 100 AS `sale (%)`, 
       COUNT(id_order) AS `count(id_order)`,
       COUNT(id_order) / ANY_VALUE(totalcount) * 100 AS `count(id_order) (%)`
FROM sales
NATURAL JOIN location
NATURAL JOIN ( SELECT s1.createdby
               FROM sales s1
               GROUP BY s1.createdby
               HAVING SUM(s1.createdAt BETWEEN '2016-02-01' AND '2018-03-04')
                  AND SUM(s1.createdAt <= '2018-03-04') > 1 ) clients
JOIN ( SELECT SUM(sale) totalsum, 
              COUNT(id_order) totalcount 
       FROM sales
       NATURAL JOIN ( SELECT s1.createdby
                      FROM sales s1
                      GROUP BY s1.createdby
                      HAVING SUM(s1.createdAt BETWEEN '2016-02-01' AND '2018-03-04')
                         AND SUM(s1.createdAt <= '2018-03-04') > 1 ) clients ) totals
GROUP BY location_city WITH ROLLUP

скрипка

...