如何根据来自不同 table 的多个条件 mysql 计算百分比
How to count percentage based on several condition mysql from different table
我有 2 个 table 像这样 sales.id_Location = location.id_location(这不是真实数据,只是虚拟数据)销售 table,id_order是交易的历史,createdAt是交易发生的日期,sale是交易的金额(公斤),id_Location是与id_location相连的发货地点table, createdby 是买家。
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;
这是fiddle
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=eac3dc2845bfa425fbd576cc18c72609
在这种情况下,我使用了 mysql 版本 5.7,我想在这种情况下找出每个位置的销售统计数据
销售额在“2016-02-01”到“2018-03-10”之间
买家(第 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;
这是fiddle
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=eac3dc2845bfa425fbd576cc18c72609
测试
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
fiddle(参见 fiddle 中的评论)。
the total on percent in sale and count id_order should be 100 because it's count overall statistic for the date range not for overall data on data dummy – 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
我有 2 个 table 像这样 sales.id_Location = location.id_location(这不是真实数据,只是虚拟数据)销售 table,id_order是交易的历史,createdAt是交易发生的日期,sale是交易的金额(公斤),id_Location是与id_location相连的发货地点table, createdby 是买家。
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;
这是fiddle https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=eac3dc2845bfa425fbd576cc18c72609
在这种情况下,我使用了 mysql 版本 5.7,我想在这种情况下找出每个位置的销售统计数据
销售额在“2016-02-01”到“2018-03-10”之间
买家(第
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;
这是fiddle https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=eac3dc2845bfa425fbd576cc18c72609
测试
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
fiddle(参见 fiddle 中的评论)。
the total on percent in sale and count id_order should be 100 because it's count overall statistic for the date range not for overall data on data dummy – 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