![](/img/trans.png)
[英]Union all customers from two tables and assign date values from second table in case customer does not exist in first table
[英]Join two tables and assign values from second table to each date of the first table
/* Table Costs */
CREATE TABLE costs (
id SERIAL PRIMARY KEY,
date DATE,
costs_per_day DECIMAL
);
INSERT INTO costs
(date, costs_per_day)
VALUES
('2020-01-01', '400'),
('2020-01-02', '400'),
('2020-01-03', '400'),
('2020-01-04', '400'),
('2020-01-05', '400'),
('2020-01-06', '400'),
('2020-01-07', '400'),
('2020-01-08', '400');
/* Table Sales */
CREATE TABLE sales (
id SERIAL PRIMARY KEY,
event_date DATE,
country VARCHAR,
sales_share DECIMAL
);
INSERT INTO sales
(event_date, country, sales_share)
VALUES
('2020-01-03', 'DE', '0.45'),
('2020-01-03', 'NL', '0.10'),
('2020-01-03', 'FR', '0.35'),
('2020-01-06', 'DE', '0.20'),
('2020-01-06', 'FR', '0.70'),
('2020-01-06', 'NL', '0.10');
预期结果:
date_list | event_date | country | sales_share | costs_per_day_per_country|
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-01 | NULL | DE | 0.33 | 133.33 |
2020-01-01 | NULL | FR | 0.33 | 133.33 |
2020-01-01 | NULL | NL | 0.33 | 133.33 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-02 | NULL | DE | 0.33 | 133.33 |
2020-01-02 | NULL | FR | 0.33 | 133.33 |
2020-01-02 | NULL | NL | 0.33 | 133.33 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-03 | 2020-01-03 | DE | 0.45 | 180.00 |
2020-01-03 | 2020-01-03 | FR | 0.35 | 140.00 |
2020-01-03 | 2020-01-03 | NL | 0.10 | 40.00 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-04 | NULL | DE | 0.33 | 133.33 |
2020-01-04 | NULL | FR | 0.33 | 133.33 |
2020-01-04 | NULL | NL | 0.33 | 133.33 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-05 | NULL | DE | 0.33 | 133.33 |
2020-01-05 | NULL | NL | 0.33 | 133.33 |
2020-01-05 | NULL | FR | 0.33 | 133.33 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-06 | 2020-01-06 | DE | 0.20 | 80.00 |
2020-01-06 | 2020-01-06 | NL | 0.70 | 280.00 |
2020-01-06 | 2020-01-06 | FR | 0.10 | 40.00 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-07 | NULL | DE | 0.33 | 133.33 |
2020-01-07 | NULL | NL | 0.33 | 133.33 |
2020-01-07 | NULL | FR | 0.33 | 133.33 |
--------------|----------------|---------------|--------------------|--------------------------|
2020-01-08 | NULL | DE | 0.33 | 133.33 |
2020-01-08 | NULL | NL | 0.33 | 133.33 |
2020-01-08 | NULL | FR | 0.33 | 133.33 |
我想将表costs
和sales
与以下条件合并:
costs
中的所有日期。costs
中的每个日期都从表格sales
中分配了所有可用的国家/地区。dates
匹配,则分配表sales
中的sales_share
。sales_share
将平均分配给国家/地区的数量。costs_per_day
sales_share
得到costs_per_day_per_country
。到目前为止,我能够开发这个查询:
SELECT
c.date AS date_list,
t1.event_date,
t1.country,
t1.sales_share,
c.costs_per_day * t1.sales_share AS costs_per_day_per_country
FROM costs c
LEFT JOIN
(SELECT
DISTINCT s.event_date,
s.sales_share,
s.country
FROM sales s
ORDER BY 1,2) t1 ON t1.event_date = c.date
ORDER BY 1,2,3;
通过这个查询,我已经能够从条件中执行要点1)
、 3)
和5)
的某些部分。
我认为我最大的问题是将国家/地区放在列表中的每个日期,如2)
中所述。
如何修改查询以获得整个预期结果?
使用具有不同国家/地区的 CROSS JOIN 将每个日期分配到所有可用国家/地区,然后按日期和国家/地区加入销售。 根据 t1 是否加入来计算 cost_per_day_per_country。 像这样的东西:
SELECT
c.date AS date_list,
t1.event_date,
co.country,
coalesce(t1.sales_share,
(1-sum(COALESCE(t1.sales_share,0)) over (partition by c.date))/ --share to divide
count(case when t1.sales_share is null then 1 end) over(partition by c.date) --number of countries not joined
) as sales_share,
case when t1.sales_share is NULL --Not joined
then c.costs_per_day *
(1-sum(COALESCE(t1.sales_share,0)) over (partition by c.date))/ --share to divide
count(case when t1.sales_share is null then 1 end) over(partition by c.date) --number of countries not joined
else c.costs_per_day * t1.sales_share
end AS costs_per_day_per_country
FROM costs c
CROSS JOIN (select distinct s.country from sales s) co
LEFT JOIN
(SELECT
DISTINCT s.event_date,
s.sales_share,
s.country
FROM sales s) t1 ON t1.event_date = c.date AND t1.country = co.country
ORDER BY 1,2,3;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.