我正在使用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
。)
但是,我如何获得月份和组织的所有唯一行,并且只有然后左右加入支出?
答案 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表中错过了一些
我认为其余的都是微不足道的,你已经有了主要代码。 如果这不准确,请告诉我,您需要帮助完成上述步骤