繁体   English   中英

连接两个表并将第二个表中的值分配给第一个表的每个日期

[英]Join two tables and assign values from second table to each date of the first table

DB-小提琴

/* 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           |

我想将表costssales与以下条件合并:

  1. 列出了表costs中的所有日期。
  2. 表格costs中的每个日期都从表格sales中分配了所有可用的国家/地区。
  3. 如果两个表中的dates匹配,则分配表sales中的sales_share
  4. 如果它们不匹配,则sales_share将平均分配给国家/地区的数量。
  5. cost_per_day 与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;

DB-小提琴

暂无
暂无

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

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