表的交叉表函数未携带

时间:2017-03-17 23:26:13

标签: postgresql pivot-table crosstab

我当前的sae_table(id,cbid,description,value)如图所示。

我想转动它,所以看起来像这样:

id     cbid    month    day   year    test   actual_value   normal_ran   no
1    60051     09       27    2016  "Urinary" "some vegetans"
2    60051     09       30    2016  "Chest"   
3    60052  ....

我已尝试使用id,description和value执行交叉表,但所有值仅显示在Month列下。

SELECT * FROM CROSSTAB('SELECT id, description,value from sae_test')
 AS ct ("id" integer,  "Month" character varying(4000),"Day" character varying(4000),"Year" character varying (4000),
 "Test" character varying(4000),"Actual Value" character varying(4000),"Normal Range" character varying(4000),"No Test option" character varying(4000));

以上交叉表结果(值不能正确分配列):

id    Month    Day   Year     ...
1      09                     ...
2      27                     ...
3      2016                   ...

我还尝试使用cbid,description和value进行旋转。但它只显示出独特的cbids。在这种情况下,一个cbid可以有多行。

SELECT * FROM CROSSTAB('SELECT * from sae_rel_data2()')
 AS ct ("CBID" character varying(4000), "Month" character varying(4000),"Day" character varying(4000),"Year" character varying (4000),
 "Test" character varying(4000),"Actual Value" character varying(4000),"Normal Range" character varying(4000),"No Test" character varying(4000));

上面查询的结果是(在同一个cbid中删除第二个条目,当这些条目应该被保留时):

cbid    month   day    year   ...
60051    09     27     2016   ...
60052                         ...
60053    09     27     2016   ...
60029                         ...

enter image description here

更新:

如果我有序号来帮助识别CBID的第n条记录怎么办?然后我可以创建一个循环函数,它将在每个序数级别为cbid执行交叉表,然后将每个函数与UNION或JOIN语句组合在一起吗?那会有用吗?如果是这样,那么如何创建该循环?我不熟悉它。

示例:

event_crf_id;        description,            value,        ordinal
444;                 "CBID";                "60051";          1
444;                 "Month";               "09";             1
444;                  "Day";                "27";             1
444;                  "Year";               "2016";           1
444;                  "Test";         "Urinary tract US";     1
444;               "Actual Value";   "some vegetans lesions"; 1
444;                 "Normal Range";         "";              1
444;               "No tests option";        "";              1
444;                 "Month";                "09";            2
444;                 "Day";                  "30";            2
444;                 "Year";                "2016";           2
444;                 "Test";             "Chest/abdomen CT";  2
444;             "Actual Value";         "3 bladder lesions"; 2
444;              "Normal Range";              "";            2
444;             "No tests option";            "";            2

类似的东西:

count=count (distinct ordinal) from sae_test()
for each event_crf_id in (select * from sae_test() where ordinal=count)
   SELECT * FROM CROSSTAB('SELECT event_crf_id, description, value from sae_test()) 
 JOIN ...
count=count+1

有可能吗?如何进行此连接?或者postgres是否自动知道在循环中新条目将继续添加到表中? (对不起,我对Postgres和数据库一般都是新手)

1 个答案:

答案 0 :(得分:0)

我确实必须以艰难,不成熟的方式做到这一点。但它确实为我提供了我想要的结果。我怎样才能以更复杂,更有效的方式做到这一点?

Select a.event_crf_id, rel_test_CBID, a.row_number, a.rel_test_name, rel_test_actual_value, rel_test_month, rel_test_day, rel_test_year, rel_test_normal_range From (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_name
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and i.description = 'Test') as a

left join (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_actual_value
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and i.description = 'Actual Value') as b
on a.event_crf_id = b.event_crf_id and a.row_number = b.row_number

left join (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_month
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and i.description = 'Month') as c
on a.event_crf_id = c.event_crf_id and a.row_number = c.row_number

left join (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_day
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and i.description = 'Day') as d
on a.event_crf_id = d.event_crf_id and a.row_number = d.row_number

left join (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_year
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and i.description = 'Year') as e
on a.event_crf_id = e.event_crf_id and a.row_number = e.row_number

left join (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_normal_range
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and i.description = 'Normal Range') as f
on a.event_crf_id = f.event_crf_id and a.row_number = f.row_number

left join (Select id.event_crf_id, id.ordinal as row_number, id.value as rel_test_CBID
from item i, item_data id 
where i.item_id=id.item_ID and id.item_id IN (2185,2262,2263,2264,2265,2266,2267,2268) and id.ordinal = 1 and i.description = 'CBID') as g
on a.event_crf_id = g.event_crf_id

order by a.event_crf_id, a.row_number asc;