postgres表达式从数组中选择元素

时间:2016-12-17 12:49:14

标签: postgresql

我想从数组列中选择某些元素。我知道你可以按位置来做,但我想过滤内容。这是我的数据:

     table_name      |       column_names
---------------------+---------------------------------------------------------------
attribute_definition | {attribute_type_concept_id}
cohort_definition    | {definition_type_concept_id,subject_concept_id}
condition_occurrence | {condition_concept_id,condition_source_concept_id,condition_type_concept_id}
death                | {cause_concept_id,cause_source_concept_id,death_impute_concept_id,death_type_concept_id}
device_exposure      | {device_concept_id,device_source_concept_id,device_type_concept_id}
drug_exposure        | {dose_unit_concept_id,drug_concept_id,drug_source_concept_id,drug_type_concept_id,route_concept_id}

我想说的是:

SELECT table_name,
       array_agg(SELECT colname FROM column_names WHERE colname LIKE '%type%') AS type_cols,
       array_agg(SELECT colname FROM column_names WHERE colname NOT LIKE '%type%') AS other_cols
FROM mytable
GROUP BY table_name

我想要的结果是:

     table_name      |     type_cols                |     other_cols
----------------------+--------------------------------------------------------------------------------------------------------------
attribute_definition | {attribute_type_concept_id}  | {}                                                                          
cohort_definition    | {definition_type_concept_id} | {subject_concept_id}                                                      
condition_occurrence | {condition_type_concept_id}  | {condition_concept_id,condition_source_concept_id}                         
death                | {death_type_concept_id}      | {cause_concept_id,cause_source_concept_id,death_impute_concept_id}             
device_exposure      | {device_type_concept_id}     | {device_concept_id,device_source_concept_id}                                  
drug_exposure        | {drug_type_concept_id}       | {dose_unit_concept_id,drug_concept_id,drug_source_concept_id,route_concept_id}  

所以,我希望最终得到相同数量的行但不同的列。必须有一个简单的方法来做到这一点。为什么我找不到它?

2 个答案:

答案 0 :(得分:2)

unnest是你的朋友。如:

SELECT table_name,
       array(SELECT colname FROM unnest(column_names) AS colname WHERE colname LIKE '%type%') AS type_cols,
       array(SELECT colname FROM unnest(column_names) AS colname WHERE colname NOT LIKE '%type%') AS other_cols
FROM mytable
GROUP BY table_name, column_names

答案 1 :(得分:1)

以下是Dan Getz的答案,但是在一个自包含的声明中,所以它很容易运行而不会复制我的数据。

with grps as
(
  with numlist as
  (
    select '1 - 10' as grp, generate_series(1,10) num
    union
    select '11 - 20', generate_series(11,20) order by 1,2
  )
  select grp, array_agg(num) as nums
  from numlist
  group by 1
)
select grp,
        (select array_agg(evens) from unnest(nums) as evens where evens % 2 = 0) as evens,
        (select array_agg(odds) from unnest(nums) as odds where odds % 2 != 0) as odds
from grps
group by grp, nums;

   grp   |      evens       |       odds
---------+------------------+------------------
 11 - 20 | {12,14,16,18,20} | {11,13,15,17,19}
 1 - 10  | {2,4,6,8,10}     | {1,3,5,7,9}