如果一年内没有发生销售,则缺失行与其他

Posted

技术标签:

【中文标题】如果一年内没有发生销售,则缺失行与其他【英文标题】:missing row if sales did not occur in one year vs other 【发布时间】:2020-02-14 21:25:27 【问题描述】:

下面是表定义和数据:

CREATE TABLE bike
(
  id INTEGER,
  name VARCHAR(50),
  price INTEGER
);

CREATE TABLE country
(
  id INTEGER,
  country VARCHAR(50)
);

create table bike_sales
(
  bike_id int,
  country_id int,
  quantity int,
  sales_date DATE
);
INSERT INTO bike VALUES(1,'XYZ',50000);
INSERT INTO bike VALUES(2,'ABC',70000);
INSERT INTO bike VALUES(3,'PQR',70000);

INSERT INTO country VALUES(1,'US');
INSERT INTO country VALUES(2,'Canada');
INSERT INTO country VALUES(3,'UK');

INSERT INTO bike_sales VALUES(1, 1, 5, '2018-01-01');
INSERT INTO bike_sales VALUES(1, 2, 10, '2018-02-01');
INSERT INTO bike_sales VALUES(1, 3, 7, '2018-03-01');
INSERT INTO bike_sales VALUES(2, 1, 9, '2018-04-01');
INSERT INTO bike_sales VALUES(2, 2, 8, '2018-05-01');
INSERT INTO bike_sales VALUES(2, 3, 4, '2018-06-01');
INSERT INTO bike_sales VALUES(3, 3, 4, '2019-06-01');

当我运行这个查询时:

SELECT c.country, b.name, (bs.quantity* b.price) as revenue 
FROM bike_sales bs 
  LEFT JOIN country c
    ON c.id = bs.country_id
  LEFT JOIN bike b
    ON b.id = bs.bike_id 
WHERE year(bs.sales_date) = '2018'
order by c.country, b.name

我得到这个输出

+---------+------+---------+
| country | name | revenue |
+---------+------+---------+
| Canada  | ABC  |  560000 |
| Canada  | XYZ  |  500000 |
| UK      | ABC  |  280000 |
| UK      | PQR  |  280000 |
| UK      | XYZ  |  350000 |
| US      | ABC  |  630000 |
| US      | XYZ  |  250000 
+---------+------+---------+

我正在计算 2018 年全国范围内的销售额。我还希望我的结果显示 2019 年售出的自行车,即使它们在 2018 年没有售出。例如:“英国”没有“PQR”的销售额在 2018 年,虽然它于 2019 年在英国销售,但由于 2018 年没有销售,我在输出中也需要该行,收入为 0。我如何得到这个缺失的行?

| UK      | ABC  |  0 |

【问题讨论】:

【参考方案1】:

从您现有的查询开始,您可以过滤 2018 年 2019 年,并在计算收入时使用 case 表达式:

select 
    c.country, 
    b.name, 
    case when year(bs.sales_date) = 2018 THEN bs.quantity * b.price else 0 end as revenue 
from 
    bike_sales bs
    left join country c on c.id = bs.country_id
    left join bike b on b.id = bs.bike_id 
where year(bs.sales_date) in (2018, 2019)
order by c.country, b.name

Demo on DB Fiddle

| country | name | revenue |
| ------- | ---- | ------- |
| Canada  | ABC  | 560000  |
| Canada  | XYZ  | 500000  |
| UK      | ABC  | 280000  |
| UK      | PQR  | 0       |
| UK      | XYZ  | 350000  |
| US      | ABC  | 630000  |
| US      | XYZ  | 250000  |

旁注:mysql 函数year() 返回一个数字(不是字符串)。

【讨论】:

以上是关于如果一年内没有发生销售,则缺失行与其他的主要内容,如果未能解决你的问题,请参考以下文章

检测某个事件的缺失

确定何时没有数据库行与 Python mysql.connector 匹配

获得客户一年内的首次购买

兔子的繁殖

如何用sql的日期函数,分别查出1月~12月每个月的销售金额?

如何将当前行与另一行进行比较