在进行LEFT JOIN之前,如何创建日期列表?

时间:2015-12-09 12:56:43

标签: sql google-bigquery

我正在使用BigQuery SQL。我有以下表格:

List<List<YourClass>> grouped = ListOfItens
    .GroupBy(x => new {x.X, x.Y})
    .Select(g => g.ToList())
    .ToList();

我想按组织计算每月按特定化学品的支出。复杂的是,如果一个组织在一个月内没有花费该化学品,那么Table "public.org" (records all organisations) Column │ Type │ Modifiers ──────────────┼────────────────────────┼─────────── code │ character varying(6) │ not null name │ character varying(200) │ not null setting │ integer │ not null Table "public.spending" (records spending on chemical by org by month) Column │ Type │ Modifiers ───────────────────┼─────────────────────────┼─────────── org_id │ character varying(6) │ not null month │ date │ not null chemical_id │ character varying(9) │ not null actual_cost │ double precision │ not null 表中根本没有条目,而不是零条目。但是,我想输出(null或零结果,我不介意哪个)。

现在我有了这个,这给了我所有组织的总支出,包括没有参赛作品的组织,但没有按月分开支出:

spending

所以现在我需要扩展它以按月组织进行LEFT JOIN。我知道通过这样做,我可以在SELECT org.code AS code, org.name AS name, num.actual_cost as actual_cost FROM ( SELECT code, name FROM org WHERE setting=4) AS orgs LEFT OUTER JOIN EACH ( SELECT org_id, SUM(actual_cost) AS actual_cost FROM spending WHERE chemical_id='1202010U0AAAAAA' GROUP BY org_id) AS num ON num.org_id = orgs.code 表中获得独特的月份:

spending

(NB BigQuery不支持SELECT month FROM spending GROUP BY month 。)

但是,我如何获得月份组织的所有唯一行,并且只有然后左右加入支出?

3 个答案:

答案 0 :(得分:1)

如果我们谈论日历月,我们只有12个选项(Jan =&gt; Dec)。

只需编译一个静态表,或者在查询本身中选择12表,然后使用它来加入。

select * from 
(select 1 as m),
(select 2 as m),
....
(select 12 as m)

您可能也对其他帖子中提到的技术感兴趣:

答案 1 :(得分:0)

我不确定这是否适用于bigquery,但这是一个符合你想要的查询结构:

select org.name, org.code, m.month, sum(s.actual_cost)
from org cross join
     (select month from public.spending group by month) m left join
     pubic.spending s
     on s.ord_ig = org.code and s.month = m.month
where prescribing_setting = 4
group by org.name, org.code, m.month;

答案 2 :(得分:0)

我建议您按照以下步骤进行操作:

第1步 - 确定月份范围(开始和结束)
假设月份以YYYY-MM-01格式呈现 如果它的格式不同 - 代码应略微调整

SELECT 
  MIN(month) as start, 
  MAX(month) as finish
FROM public.spending

假设步骤1的结果是 '2014-10-01'开始,'2015-05-01'完成

第2步 - 生成开始和结束之间的所有月份

SELECT DATE(DATE_ADD(TIMESTAMP('2000-01-01'), pos - 1, "MONTH")) AS month
FROM (
  SELECT ROW_NUMBER() OVER() AS pos, * FROM (FLATTEN((
  SELECT SPLIT(RPAD('', 1000, '.'),'') AS h FROM (SELECT NULL)),h
))) nums 
CROSS JOIN (
  SELECT '2014-10-01' AS start, '2015-05-01' AS finish // <<-- Replace with SELECT from Step 1
) range
WHERE pos BETWEEN 1 AND 1000
AND DATE(DATE_ADD(TIMESTAMP('2000-01-01'), pos - 1, "MONTH")) 
    BETWEEN start AND finish

所以,现在 - 第2步的结果

month    
2014-10-01   
2014-11-01   
2014-12-01   
2015-01-01   
2015-02-01   
2015-03-01   
2015-04-01   
2015-05-01

它有几个月,即使在开始和结束之间的public.spending表中错过了一些

我认为其余的都是微不足道的,你已经有了主要代码。 如果这不准确,请告诉我,您需要帮助完成上述步骤