简体   繁体   English

将一个表中基于每日的值与另一个表中基于季度的值相乘

[英]Multiply daily-based values from one table with quarter-based values from another table

DB-Fiddle DB-小提琴

/* Sales */
CREATE TABLE sales (
    id int auto_increment primary key,
    category VARCHAR(255),
    sales_date DATE,
    sales_volume INT
);

INSERT INTO sales
(category, sales_date, sales_volume
)
VALUES 
("Category_01", "2020-01-03", "500"),
("Category_01", "2020-04-15", "700"),
("Category_01", "2020-08-27", "180"),
("Category_01", "2020-09-29", "320"),
("Category_02", "2020-07-17", "420"),
("Category_02", "2020-12-24", "350"),
("Category_02", "2020-12-08", "570"),
("Category_03", "2020-01-10", "180"),
("Category_03", "2020-10-20", "970");


/* Return Risk */
CREATE TABLE return_risk (
    id int auto_increment primary key,
    category VARCHAR(255),
    quarter VARCHAR(255),
    return_risk_rate DECIMAL(5,2)
);

INSERT INTO return_risk
(category, quarter, return_risk_rate
)
VALUES 
("Category_01", "2019-Q1", "0.40"),
("Category_01", "2019-Q2", "0.45"),
("Category_01", "2019-Q3", "0.52"),
("Category_01", "2019-Q4", "0.67"),
("Category_02", "2019-Q1", "0.32"),
("Category_02", "2019-Q2", "0.47"),
("Category_02", "2019-Q3", "0.25"),
("Category_02", "2019-Q4", "0.32"),
("Category_03", "2019-Q1", "0.40"),
("Category_03", "2019-Q2", "0.52"),
("Category_03", "2019-Q3", "0.48"),
("Category_03", "2019-Q4", "0.61");

Expected Result:预期结果:

category          quarter          sales      return_risk_percentage      return_risk_value
Category_01       2020-Q1          500             0.40                        200
Category_01       2020-Q2          700             0.45                        315
Category_01       2020-Q3          500             0.52                        260
Category_01       2020-Q4            0             0.67                          0
Category_02       2020-Q1            0             0.32                          0
Category_02       2020-Q2            0             0.47                          0
Category_02       2020-Q3          420             0.25                        105     
Category_02       2020-Q4          920             0.32                        294.4
Category_03       2020-Q1          180             0.40                         72
Category_03       2020-Q2            0             0.52                          0
Category_03       2020-Q3            0             0.48                          0
Category_03       2020-Q4          970             0.61                        591.7

As you can see I have two tables called sales and return_risk .如您所见,我有两个表,分别称为salesreturn_risk
In the table return_risk an average percentage rate per quarter of the last year is calculated.在表return_risk中计算了去年每季度的平均百分比率。

This average return rate should be applied to the sales of the current year .这个平均回报率应该适用于当年sales
So far I came up with this query:到目前为止,我想出了这个查询:

SELECT
s.category,
r.quarter,
r.return_risk_rate AS return_risk_%,
(s.category * r.return_risk_rate) AS return_risk_value
FROM sales s
JOIN return_risk r ON r.category = s.category
GROUP BY 1,2;

The issue is that I do not know how I can connect the date values in column sales_date with the corresponding quarter in table return_risk to apply the correct percentage rate for each category and quarter .问题是我不知道如何将列sales_date中的date values与表return_risk中的相应quarter联系起来,以便为每个categoryquarter应用正确的百分比。

Do you have any idea how I can achieve this?你知道我怎么能做到这一点吗?

Consider the following, which includes an amendment from my earlier solution, allowing use of an index...考虑以下内容,其中包括对我早期解决方案的修改,允许使用索引......

DROP TABLE IF EXISTS  sales;

CREATE TABLE sales (
    id int auto_increment primary key,
    category_id INT NOT NULL,
    sales_date DATE NOT NULL,
    sales_volume INT NOT NULL,
    INDEX(category_id,sales_date)
);

INSERT INTO sales
(category_id, sales_date, sales_volume
)
VALUES 
(1, "2020-01-03", 500),
(1, "2020-04-15", 700),
(1, "2020-08-27", 180),
(1, "2020-09-29", 320),
(2, "2020-07-17", 420),
(2, "2020-12-24", 350),
(2, "2020-12-08", 570),
(3, "2020-01-10", 180),
(3, "2020-10-20", 970);


DROP TABLE IF EXISTS  return_risk;

CREATE TABLE return_risk (
    category_id INT NOT NULL,
    year INT NOT NULL,
    quarter INT NOT NULL,
    return_risk_rate DECIMAL(5,2),
    PRIMARY KEY(category_id,year,quarter)
);

INSERT INTO return_risk
(category_id, year,quarter, return_risk_rate
)
VALUES 
(1, 2019,1,0.40),
(1, 2019,2,0.45),
(1, 2019,3,0.52),
(1, 2019,4,0.67),
(2, 2019,1,0.32),
(2, 2019,2,0.47),
(2, 2019,3,0.25),
(2, 2019,4,0.32),
(3, 2019,1,0.40),
(3, 2019,2,0.52),
(3, 2019,3,0.48),
(3, 2019,4,0.61);

SELECT s.*
     , r.return_risk_rate
     , r.return_risk_rate * sales_volume expected_return
  FROM sales s 
  JOIN return_risk r 
    ON r.category_id = s.category_id
   AND s.sales_date >= CONCAT_WS('-','2020',LPAD((r.quarter*3)-2,2,'0'),'01') 
   AND s.sales_date < CONCAT_WS('-','2020',LPAD((r.quarter*3),2,'0'),'01')+INTERVAL 1 MONTH - INTERVAL 1 DAY;

+----+-------------+------------+--------------+------------------+-----------------+
| id | category_id | sales_date | sales_volume | return_risk_rate | expected_return |
+----+-------------+------------+--------------+------------------+-----------------+
|  1 |           1 | 2020-01-03 |          500 |             0.40 |          200.00 |
|  2 |           1 | 2020-04-15 |          700 |             0.45 |          315.00 |
|  3 |           1 | 2020-08-27 |          180 |             0.52 |           93.60 |
|  4 |           1 | 2020-09-29 |          320 |             0.52 |          166.40 |
|  5 |           2 | 2020-07-17 |          420 |             0.25 |          105.00 |
|  6 |           2 | 2020-12-24 |          350 |             0.32 |          112.00 |
|  7 |           2 | 2020-12-08 |          570 |             0.32 |          182.40 |
|  8 |           3 | 2020-01-10 |          180 |             0.40 |           72.00 |
|  9 |           3 | 2020-10-20 |          970 |             0.61 |          591.70 |
+----+-------------+------------+--------------+------------------+-----------------+

You should make note of the suggestions @Strawberry makes in terms of improving your data structure as it will simplify and make your query faster.您应该记下@Strawberry 在改进数据结构方面提出的建议,因为它将简化并使您的查询更快。 In the interim, you can use this query with your existing data (but note I had to change the quarter values in return_risk to 2020 to get any results).在此期间,您可以将此查询与现有数据一起使用(但请注意,我必须将return_risk中的季度值更改为 2020 才能获得任何结果)。 It LEFT JOIN s return_risk to sales on the category and quarter (which is manually constructed from the sales_date field:LEFT JOINreturn_riskcategory和季度的sales (这是从sales_date字段手动构建的:

SELECT r.category,
       r.quarter,
       COALESCE(SUM(s.sales_volume), 0) AS sales,
       r.return_risk_rate AS `return_risk_%`,
       COALESCE(SUM(s.sales_volume) * r.return_risk_rate, 0) AS return_risk_value
FROM return_risk r
LEFT JOIN sales s ON r.category = s.category
                 AND r.quarter = CONCAT(YEAR(sales_date), '-Q', QUARTER(sales_date))
GROUP BY r.category, r.quarter, r.return_risk_rate
ORDER BY r.category, r.quarter

Output: Output:

category        quarter     sales   return_risk_%   return_risk_value
Category_01     2020-Q1     500     0.40            200.00
Category_01     2020-Q2     700     0.45            315.00
Category_01     2020-Q3     500     0.52            260.00
Category_01     2020-Q4     0       0.67            0.00
Category_02     2020-Q1     0       0.32            0.00
Category_02     2020-Q2     0       0.47            0.00
Category_02     2020-Q3     420     0.25            105.00
Category_02     2020-Q4     920     0.32            294.40
Category_03     2020-Q1     180     0.40            72.00
Category_03     2020-Q2     0       0.52            0.00
Category_03     2020-Q3     0       0.48            0.00
Category_03     2020-Q4     970     0.61            591.70

Demo on dbfiddle dbfiddle 上的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM