2011-07-27 39 views
3

私はこのサイトのいくつかの提案を検索してきましたが、私はちょうど足りない文法/句読点の問題があると思う。PostgreSQLの複数のテーブルにわたる複数の合計/カウント

私は、調査対象のヒヒの個体群に関連する多くの情報を追跡するphpPgAdminを使用してデータベースを操作します。私は、それぞれのヒヒについて、私たちが収集した異なるタイプの組織サンプルの数と、それぞれに異なるタイプのDNAサンプルの数を特定するクエリを作成しようとしています。私の問題:

テーブル: "伝記"はグループのすべての動物に関する基本情報を持っていますが、名前は私がここで気にしています。

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

表:「babtissue」は、長年にわたって収集された異なる組織に関する情報(以下の3つの列を含む)を追跡する。この表の一部の行は、もはや持っていない組織サンプルを表していますが、データベースの他の場所でも参照されています。したがって、 "avail"列は、まだ残っているサンプルをスクリーニングするのに役立ちます。

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

表: "dna"はbabtissueに似ています。全体で

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

は、私がbiographからすべての名前を返し、1列に私に指示しますクエリを記述しようとしているどのように多くの「BLOOD」、「組織」、「gDNAを」、および「WGA」サンプルIそれぞれの個性があります。以下のような何か...

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 

このようにしてもエラーは発生しませんが、私に与えられた数字は間違っています。これは私が複数の結合を使用していることと関係があり、結合構文に関する何かを変更する必要があることがわかります。

アイデア?

+0

は私にはOKに見えます。 –

+0

私はあなたの書式を整理しましたが、 'avail'カラムにあなたが何を望んでいるのか分からなかったので、'? 'をそこに残しました。 –

+0

ありがとう、@ムが短すぎます。 – Jake

答えて

4

babtissueに参加しているため数字が高すぎます。また、重複の原因になるのはdnaになります。

あなたはそれを分解しようとすることができます。名前が本当にNULLすることができます...

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 

をこの構文は、データベースのために働くかどうかはわからないが、私はそれはANSI規格に準拠することを信じているので、それに打撃を与えますか?

+0

PostgreSQLはこれをすべて処理できます。 –

+0

ええと、@Tom H.、nameはnullでもかまいません。そのテーブルには他のいくつかの列があります(無関係の情報を省略しようとしました)、人口に生まれたすべての人のための行が含まれています。動物の多くは出生直後に死ぬので、決して名前が付けられません。 私はこのクエリを試してみましたが、修正できた小さなエラーがいくつかありました。サブクエリには 'GROUP BY B.name'が必要でした。最後に 'GROUP BY'にはSQ.gdnasとSQ.wgasを含める必要がありました。しかし、それらを追加すると、うまくいった! ありがとう! – Jake

+0

@Jake:申し訳ありませんが、私は通常の "あいまいなGROUP BY"問題を発見したはずですが、修正するのは簡単でした。 Tomの答えの横の[チェックマークをクリックする](http://stackoverflow.com/faq#howtoask)で回答を受け入れることができます。 –

1

私が「役に立つ」欄については知りませんが、これはあなたが探している他の列を与える必要があります:

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) 
; 
関連する問題