查询以外键联接4个表并按日期分组

时间:2020-03-13 13:48:58

标签: mysql sql

我试图加入4张桌子。我将收到每月显示的销售和索赔产品清单。 有4种组合需要考虑:

  1. 产品已在特定月份售出,我们已索赔。
  2. 某个月没有销售产品,我们对此有索赔。
  3. 产品已在特定月份出售,我们没有任何索赔。
  4. 某个月没有销售产品,我们也没有索赔。

    我开始认为可能有必要创建日期表。

select
   ps.date,
   cl.date,
   ps.part_number,
   ps.sales_quantity,
   cl.claims_quantity
from (select convert(varchar(7), s.date, 120) as date, p.part_number, sum(id.quantity) as sales_quantity
   from parts as p
   left outer join invoice_details as id
   on p.part_number = id.part_number
   left outer join sales as s
   on id.invoice = s.invoice
   group by convert(varchar(7), s.date, 120), p.part_number
   ) ps join 
   (select convert(varchar(7), c.date_registered, 120) as date, p.part_number, sum(c.quantity) as claims_quantity
   from parts as p
   left outer join claims as c
   on p.part_number = c.part_number
   group by convert(varchar(7), c.date_registered, 120), p.part_number
   ) cl
   on ps.part_number = cl.part_number
group by ps.date, cl.date, ps.part_number, ps.sales_quantity, cl.claims_quantity
order by cl.claims_quantity desc

enter image description here

2 个答案:

答案 0 :(得分:1)

如果我的理解正确,您希望每个部分和每个月都有一行。如果是这样,则您需要某种生成月份的方法-因为它们可能不在数据中。

然后,使用left join引入数据和汇总以获取所需的信息:

select p.part_number, m.mon,
       sum(sales_quantity), sum(claim_quantity)
from parts p cross join
     (select date('2020-01-01') as mon union all
      select date('2020-02-01') as mon 
     ) m left join
     ((select s.date, id.part_number, id.quantity as sale_quantity, null as claim_quantity
       from sales s join
            invoice_details id
            on id.id_sale = s.id_sale
      ) union all
      (select c.date_registered, null, null, quantity
       from claims
      )
     ) sc
     on sc.part_number = p.part_number and
        sc.date >= m.mon and
        sc.date < m.mon + interval 1 month
group by p.part_number, m.mon

答案 1 :(得分:0)

以下代码未给出正确的结果

declare @date1 date='2019-02-01';
declare @date2 date='2019-03-01';
declare @date3 date='2019-04-01';
declare @date4 date='2019-05-01';
declare @date5 date='2019-06-01';
declare @date6 date='2019-07-01';
declare @date7 date='2019-08-01';
declare @date8 date='2019-09-01';
declare @date9 date='2019-10-01';
declare @date10 date='2019-11-01';
declare @date11 date='2019-12-01';

select p.part_number, m.mon,
       sum(sales_quantity) AS SALES, sum(claim_quantity) AS CLAIMS
from parts p cross join 
     (select @date as mon union all
     select @date1 as mon union all
     select @date2 as mon union all
     select @date3 as mon union all
     select @date4 as mon union all
     select @date5 as mon union all
     select @date6 as mon union all
     select @date7 as mon union all
     select @date8 as mon union all
     select @date9 as mon union all
     select @date10 as mon union all
     select @date11 as mon
     ) m left join
     ((select s.date, id.part_number, id.quantity as sales_quantity, null as claim_quantity
       from sales s join
            invoice_details id
            on id.invoice = s.invoice
      ) union all
      (select date_registered, part_number, null, quantity
       from claims 
      )
     ) sc
     on sc.part_number = p.part_number and
        sc.date = m.mon and 
        sc.date < DATEADD(MONTH, +1, m.mon)
    where sc.part_number = 'TC1133' 
group by p.part_number, m.mon```