优雅高效的方法来编写BigQuery中的最小值

时间:2019-09-28 11:58:11

标签: sql join google-bigquery

我有一个如下所示的表结构

enter image description here

我想做的是找到每组物品的最小值。我必须不断寻找不同组itemid的最小值。尽管我的代码有效,但是请确保这不是一种优雅而有效的方法。

查找最小WHERE itemid IN(1,2)

select subject_id,icu_id,value as min_val_1 FROM
(SELECT c.subject_id,c.time_1,d.min_time,d.max_time,c.value,c.icu_id,
row_number() OVER (PARTITION BY c.subject_id ORDER BY c.value,c.time_1) AS rank
from table_1 d
left join table_2 c 
on c.subject_id = d.subject_id and (c.icu_id = d.icu_id_1 or c.icu_id = d.icu_id_2)
where c. itemid in 
(1,2)) SBP
where rank = 1
order by subject_id,charttime

在(3,4)中的itemid中查找最小值

select subject_id,icu_id,value as min_val_2 FROM
(SELECT c.subject_id,c.time_1,d.min_time,d.max_time,c.value,c.icu_id,
row_number() OVER (PARTITION BY c.subject_id ORDER BY c.value,c.time_1) AS rank
from table_1 d
left join table_2 c 
on c.subject_id = d.subject_id and (c.icu_id = d.icu_id_1 or c.icu_id = d.icu_id_2)
where c. itemid in 
(3,4)) SBP
where rank = 1
order by subject_id

您可以看到一切都一样。唯一的区别是itemid。是否有任何优雅的方式来合并/合并这两个?你能帮我吗?

我希望我的输出像这样吗?

enter image description here

2 个答案:

答案 0 :(得分:1)

我认为您只需要条件聚合:

select t2.subject_id, t2.icu_id,
       min(case when t2.item_id in (1, 2) then t2.value end) as value_1,
       min(case when t2.item_id in (3, 4) then t2.value end) as value_2
from table_2 t2
group by t2.subject_id, t2.icu_id;

答案 1 :(得分:1)

下面是用于BigQuery标准SQL的代码,保留原始查询完全完整,而只是添加了缺少的空格(添加了注释,以便您可以看到一些更改/添加)

#standardSQL 
SELECT 
  subject_id,
  icu_id,
  MAX(IF(grp = 1, value, NULL)) AS min_val_1,   -- changed
  MAX(IF(grp = 2, value, NULL)) AS min_val_2    -- changed
FROM (
  SELECT 
    c.subject_id,
    c.time_1,
    d.min_time,
    d.max_time,
    c.value,c.icu_id,
    -- in below row - added element to PARTITION BY
    ROW_NUMBER() OVER (PARTITION BY c.subject_id, CASE WHEN c.itemid IN (1, 2) THEN 1 WHEN c.itemid IN (3, 4) THEN 2 END ORDER BY c.value, c.time_1) AS RANK,
    CASE WHEN c.itemid IN (1, 2) THEN 1 WHEN c.itemid IN (3, 4) THEN 2 END grp  -- added
  FROM table_1 d
  LEFT JOIN table_2 c 
  ON c.subject_id = d.subject_id AND (c.icu_id = d.icu_id_1 OR c.icu_id = d.icu_id_2)
  WHERE c.itemid IN (1, 2, 3, 4)  -- changed
) SBP
WHERE RANK = 1
GROUP BY subject_id, icu_id  -- added
ORDER BY subject_id

如果要应用于您的问题的样本数据-结果为

Row subject_id  icu_id  min_val_1   min_val_2    
1   124         A1      10          19   
2   199         B2      21          21