корректный способ создать сводную таблицу в postgresql использование СЛУЧАЯ, КОГДА

Я пытаюсь создать представление типа сводной таблицы в postgresql и почти там! Вот основной запрос:

select 
acc2tax_node.acc, tax_node.name, tax_node.rank 
from 
tax_node, acc2tax_node 
where 
tax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531';

И данные:

   acc    |          name           |     rank     
----------+-------------------------+--------------
 AJ012531 | Paromalostomum fusculum | species
 AJ012531 | Paromalostomum          | genus
 AJ012531 | Macrostomidae           | family
 AJ012531 | Macrostomida            | order
 AJ012531 | Macrostomorpha          | no rank
 AJ012531 | Turbellaria             | class
 AJ012531 | Platyhelminthes         | phylum
 AJ012531 | Acoelomata              | no rank
 AJ012531 | Bilateria               | no rank
 AJ012531 | Eumetazoa               | no rank
 AJ012531 | Metazoa                 | kingdom
 AJ012531 | Fungi/Metazoa group     | no rank
 AJ012531 | Eukaryota               | superkingdom
 AJ012531 | cellular organisms      | no rank

То, что я пытаюсь получить, следующее:

acc      | species                  | phylum
AJ012531 | Paromalostomum fusculum  | Platyhelminthes

Я пытаюсь сделать это со СЛУЧАЕМ, КОГДА, таким образом, я имею до следующего:

select 
acc2tax_node.acc, 
CASE tax_node.rank WHEN 'species' THEN tax_node.name ELSE NULL END as species, 
CASE tax_node.rank WHEN 'phylum' THEN tax_node.name ELSE NULL END as phylum 
from 
tax_node, acc2tax_node 
where 
tax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531';

Который дает мне вывод:

   acc    |         species         |     phylum      
----------+-------------------------+-----------------
 AJ012531 | Paromalostomum fusculum | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | Platyhelminthes
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 
 AJ012531 |                         | 

Теперь я знаю, что должен сгруппироваться acc в какой-то момент, таким образом, я пробую

select 
acc2tax_node.acc, 
CASE tax_node.rank WHEN 'species' THEN tax_node.name ELSE NULL END as sp, 
CASE tax_node.rank WHEN 'phylum' THEN tax_node.name ELSE NULL END as ph 
from 
tax_node, acc2tax_node 
where 
tax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531' 
group by acc2tax_node.acc;

Но я получаю страшное

ERROR:  column "tax_node.rank" must appear in the GROUP BY clause or be used in an aggregate function

Всеми предыдущими примерами я смог найти использование чем-то как СУММА () вокруг Операторов выбора, таким образом, я предполагаю это, является агрегатная функция. Я попытался использовать СНАЧАЛА ():

select 
acc2tax_node.acc, 
FIRST(CASE tax_node.rank WHEN 'species' THEN tax_node.name ELSE NULL END) as sp, 
FIRST(CASE tax_node.rank WHEN 'phylum' THEN tax_node.name ELSE NULL END) as ph 
from tax_node, acc2tax_node where tax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531' group by acc2tax_node.acc;

но получите ошибку:

ERROR:  function first(character varying) does not exist

Кто-либо может предложить какие-либо подсказки?

6
задан mojones 19 March 2010 в 12:34
поделиться

4 ответа

Используйте MAX () или MIN (), но не FIRST (). В этом сценарии у вас будут все значения NULL в столбце для каждого значения группы, за исключением, самое большее, одного с ненулевым значением. По определению, это и МИН, и МАКС этого набора значений (все нули исключены).

5
ответ дан 17 December 2019 в 00:07
поделиться

Дополнительная информация по запросу (в ответе, а не в комментарии для приятного форматирование):

SELECT * FROM acc2tax_node WHERE acc = 'AJ012531';

   acc    | taxid  
----------+--------
 AJ012531 |  66400
 AJ012531 |  66399
 AJ012531 |  39216
 AJ012531 |  39215
 AJ012531 | 166235
 AJ012531 | 166384
 AJ012531 |   6157
 AJ012531 |  33214
 AJ012531 |  33213
 AJ012531 |   6072
 AJ012531 |  33208
 AJ012531 |  33154
 AJ012531 |   2759
 AJ012531 | 131567
0
ответ дан 17 December 2019 в 00:07
поделиться
SELECT  atn.acc, ts.name AS species, tp.name AS phylum
FROM    acc2tax_node atn
LEFT JOIN
        tax_node ts
ON      ts.taxid = atn.taxid
        AND ts.rank = 'species'
LEFT JOIN
        tax_node tp
ON      tp.taxid = atn.taxid
        AND tp.rank = 'phylum'
WHERE   atn.acc = 'AJ012531 '
0
ответ дан 17 December 2019 в 00:07
поделиться

PostgreSQL имеет несколько функций для сводных запросов, см. Эту статью на Postgresonline . Вы можете найти эти функции в contrib .

2
ответ дан 17 December 2019 в 00:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: