2017-03-17 5 views
0

Mon actuelle sae_table (id, cbid, description, valeur) ressemble à l'image.La fonction de tableau croisé pour la table ne porte pas les valeurs

Je veux le faire pivoter, de sorte qu'il peut ressembler à ceci:

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 .... 

Je tryied faire le tableau croisé à l'aide id, la description et la valeur, mais toutes les valeurs ne se affiche dans la colonne Mois.

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)); 

Au-dessus de résultat crosstab (valeurs ne distribuent pas les colonnes accross correctement):

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

J'ai aussi essayé pivoter simplement en utilisant la CBID, la description et la valeur. Mais il ne montre que des cbids distinctifs. Et dans ce cas, un cbid peut avoir plusieurs lignes.

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)); 

Le résultat de la requête ci-dessus était (en éliminant la deuxième entrée pour la même CBID, lorsque ces entrées auraient dû être conservés):

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

enter image description here

MISE À JOUR:

Et si j'ai des nombres ordinaux qui aident à identifier les nièmes enregistrements pour un CBID? Puis-je ensuite créer une fonction de boucle qui fera le tableau croisé pour un cbid dans chaque niveau ordinal, et ensuite combiner chaque avec une instruction UNION ou JOIN? Cela fonctionnerait-il? Si oui, comment cette boucle peut-elle être créée? Je ne suis pas familier avec ça.

Exemple:

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 

Quelque chose comme:

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 

Y at-il une telle possibilité? comment cette jointure peut-elle être effectuée? ou est-ce que postgres sait automatiquement que dans une boucle les nouvelles entrées continueront à être ajoutées à la table? (désolé, je suis vraiment nouveau à Postgres et bases de données en général)

+0

Vos données sont ambigus. Quelle valeur doit être présentée pour la ligne '60051' et la colonne' Day'? Devrait-il être «27» ou «30»? (Btw, livrer vos données sous forme de texte, pas d'images). – klin

+0

Il devrait y avoir une valeur unique pour déterminer quelle date ou test ou «valeur réelle» fait partie du 2. 3. ou nième 60051? deuxième question: comment séparer chaque groupe de lignes 60051 si ces valeurs sont insérées de manière non triée? –

+0

Pensez simplement de cette façon, le numéro 60051 représente un patient, et ce patient peut avoir plusieurs laboratoires à des dates différentes. C'est pourquoi vous voyez le 60051 à plusieurs reprises. Ainsi, un cbid peut avoir plusieurs entrées, mais chaque entrée a un identifiant unique. Mais pourquoi est-ce quand je fais le SELECT * FROM CROSSTAB ('SELECT id, description, valeur de sae_test'), toutes les données sont affichées sous seulement la deuxième colonne? –

Répondre

0

Je devais littéralement faire de cette manière dure et immature. Mais cela m'a fourni les résultats que je voulais. Comment puis-je faire cela de manière plus sophistiquée et efficace?

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; 
+0

mettez votre exemple data [hier] (http://rextester.com/l/postgresql_online_compiler) avec 'insert into from your_table' de la table. –