Множественная сумма / число в нескольких таблицах в PostgreSQL - PullRequest
3 голосов
/ 27 июля 2011

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

Я работаю над базой данных с помощью phpPgAdmin, который отслеживает много информации, связанной с популяцией изучаемых бабуинов. Я пытаюсь сделать запрос, чтобы определить, для каждого отдельного павиана, сколько образцов тканей разных типов мы собрали для них и сколько образцов ДНК у нас разных типов для каждого из них. Есть три таблицы, которые имеют отношение к моя проблема:

Таблица: «Биография» содержит основную информацию обо всех животных в группе, хотя имя - это все, что меня волнует.

name | birth
-----+-----------
A21  | 1968-07-01
AAR  | 2002-03-30
ABB  | 1998-09-10
ABD  | 2005-03-15
ABE  | 1986-01-01

Таблица: «babtissue» отслеживает информацию, в том числе три столбца ниже, о различных тканях, которые были собраны за эти годы. Некоторые строки в этой таблице представляют образцы тканей, которых у нас больше нет, но они все еще упоминаются в других местах в базе данных, поэтому столбец «помог» помогает нам отследить образцы, которые у нас еще есть.

name | sample_type | avail
-----+-------------+------
A21  | BLOOD       | Y
A21  | BLOOD       | Y
A21  | TISSUE      | N
ABB  | BLOOD       | Y
ABB  | TISSUE      | Y

Таблица: «ДНК» похожа на babtissue.

name | sample_type | avail
-----+-------------+------
ABB  | GDNA        | N
ABB  | WGA         | Y
ACC  | WGA         | N
ALE  | GDNA        | Y
ALE  | GDNA        | Y

В целом, я пытаюсь написать запрос, который будет возвращать каждое имя из биографии и сообщать мне в одном столбце, сколько образцов 'BLOOD', 'TISSUE', 'GDNA' и 'WGA' у меня для каждого человека. , Что-то вроде ...

name | bloodsamps | tissuesamps | gdnas | wgas | avail
-----+------------+-------------+-------+------+------
A21  | 2          | 0           | 0     | 0    | ?
AAR  | 0          | 0           | 0     | 0    | ?
ABB  | 1          | 1           | 0     | 1    | ?
ACC  | 0          | 0           | 0     | 0    | ?
ALE  | 0          | 0           | 2     | 0    | ?

(извиняюсь за странное форматирование выше, я не очень знаком с написанием таким образом)

Последняя версия запроса, которую я пробовал:

select b.name,  
sum(case when t.sample_type='BLOOD' and t.avail='Y' then 1 else 0 end) as bloodsamps,   
sum(case when t.sample_type='TISSUE' and t.avail='Y' then 1 else 0 end) as tissuesamps,   
sum(case when d.sample_type='GDNA' and d.avail='Y' then 1 else 0 end) as gdnas,  
sum(case when d.sample_type='WGA' and d.avail='Y' then 1 else 0 end) as wgas  
from biograph b  
left join babtissue t on b.name=t.name  
left join dna d on b.name=d.name  
where b.name is not NULL  
group by b.name  
order by b.name  

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

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 27 июля 2011

Числа слишком велики, потому что вы присоединяетесь к babtissue, а затем к dna, что приведет к дублированию.

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

SELECT
    SQ.name,
    SUM(CASE WHEN T.sample_type = 'BLOOD' AND T.avail = 'Y' THEN 1 ELSE 0 END) AS bloodsamps,
    SUM(CASE WHEN T.sample_type = 'TISSUE' AND T.avail = 'Y' THEN 1 ELSE 0 END) AS tissuesamps,
    SQ.gdnas,
    SQ.wgas
FROM
    (
    SELECT
        B.name,
        SUM(CASE WHEN D.sample_type = 'GDNA' AND T.avail = 'Y' THEN 1 ELSE 0 END) AS gdnas,
        SUM(CASE WHEN D.sample_type = 'WGA' AND T.avail = 'Y' THEN 1 ELSE 0 END) AS wgas
    FROM
        biograph B
    LEFT JOIN dna D ON D.name = B.name
    GROUP BY
        B.name
    ) AS SQ
LEFT JOIN babtissue T on T.name = SQ.name
WHERE SQ.name is not NULL
GROUP BY SQ.name, SQ.gdnas, SQ.wgas
ORDER BY SQ.name

Может ли имя действительно быть NULL?

1 голос
/ 28 июля 2011

Я не знаю о столбце «результат », но это должно дать вам другие столбцы, которые вы ищете:

SELECT  b.name,
        COALESCE (t.bloodsamps,  0) AS bloodsamps,
        COALESCE (t.tissuesamps, 0) AS tissuesamps
        COALESCE (d.gdnas, 0) AS gdnas 
        COALESCE (d.wgas,  0) AS wgas
    FROM biograph b
    LEFT JOIN (
        SELECT  name,
                SUM(CASE WHEN sample_type = 'BLOOD'  THEN 1 ELSE 0 END) AS bloodsamps,
                SUM(CASE WHEN sample_type = 'TISSUE' THEN 1 ELSE 0 END) AS tissuesamps
            FROM babtissue
            WHERE avail = 'Y'
            GROUP BY name
        ) t
        ON (t.name = b.name)
    LEFT JOIN (
        SELECT  name,
                SUM(CASE WHEN sample_type = 'GDNA' THEN 1 ELSE 0 END) AS gdnas,
                SUM(CASE WHEN sample_type = 'WGA'  THEN 1 ELSE 0 END) AS wgas
            FROM dna
            WHERE avail = 'Y'
            GROUP BY name
        ) d
        ON (d.name = b.name)
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...