Элегантный и эффективный способ написать sql в bigquery - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть структура таблицы, как показано ниже

enter image description here

Я пытаюсь найти минимум для каждой группы элементов.Я должен найти минимумы для разных групп предметов.Хотя мой код работает, я уверен, что это не элегантный и эффективный способ сделать это.

поиск минимального значения 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

найти минимум, где itemid в (3,4)

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 ]

1 голос
/ 28 сентября 2019

Ниже для стандартного SQL BigQuery и оставляет ваш исходный запрос полностью нетронутым, просто добавляя недостающие фрагменты (добавлены комментарии, чтобы вы могли видеть эти несколько изменений / дополнений)

#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  
1 голос
/ 28 сентября 2019

Я думаю, вы просто хотите условную агрегацию:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...