Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL中跨多个表的多个总和/计数_Sql_Postgresql_Join_Count_Sum - Fatal编程技术网

PostgreSQL中跨多个表的多个总和/计数

PostgreSQL中跨多个表的多个总和/计数,sql,postgresql,join,count,sum,Sql,Postgresql,Join,Count,Sum,我已经在这个网站上搜索了好几条建议,还没有完全得到我想要的。我怀疑我只是遗漏了一个语法/标点符号问题 我使用phpPgAdmin开发了一个数据库,该数据库跟踪了大量与正在研究的狒狒种群相关的信息。我试图通过查询来确定,对于每只狒狒,我们为它们采集了多少不同类型的组织样本,以及我们为每只狒狒采集了多少不同类型的DNA样本。有三个表与我的问题相关: 表:“biograph”包含了该组中所有动物的基本信息,尽管这里我只关心它们的名字 name | birth -----+----------- A21

我已经在这个网站上搜索了好几条建议,还没有完全得到我想要的。我怀疑我只是遗漏了一个语法/标点符号问题

我使用phpPgAdmin开发了一个数据库,该数据库跟踪了大量与正在研究的狒狒种群相关的信息。我试图通过查询来确定,对于每只狒狒,我们为它们采集了多少不同类型的组织样本,以及我们为每只狒狒采集了多少不同类型的DNA样本。有三个表与我的问题相关:

表:“biograph”包含了该组中所有动物的基本信息,尽管这里我只关心它们的名字

name | birth
-----+-----------
A21  | 1968-07-01
AAR  | 2002-03-30
ABB  | 1998-09-10
ABD  | 2005-03-15
ABE  | 1986-01-01
表:“BabTisson”记录了多年来收集的不同组织的信息,包括以下三列。此表中的某些行表示我们不再拥有的组织样本,但仍在数据库中的其他位置引用,因此“avail”列帮助我们筛选我们仍然拥有的样本

name | sample_type | avail
-----+-------------+------
A21  | BLOOD       | Y
A21  | BLOOD       | Y
A21  | TISSUE      | N
ABB  | BLOOD       | Y
ABB  | TISSUE      | Y
表:“dna”与巴氏组织相似

name | sample_type | avail
-----+-------------+------
ABB  | GDNA        | N
ABB  | WGA         | Y
ACC  | WGA         | N
ALE  | GDNA        | Y
ALE  | GDNA        | Y
总之,我试图写一个查询,返回biograph中的每个名字,并在一列中告诉我每个人有多少“血液”、“组织”、“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  
这样做时我没有收到任何错误,但我知道它给我的数字是错误的——太高了。我想这与我使用多个连接有关,我的连接语法需要改变


有什么想法吗?

这些数字太高了,因为你要加入
BabTisson
,然后加入
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
名称真的可以为空吗?

我不知道“avail”列,但这应该会提供您要查找的其他列:

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

我整理了你的格式,但我不确定你在
avail
列中想要什么,所以我把
放在那里。谢谢你,@mu太短了。PostgreSQL可以处理所有这些。是的,@Tom H.,name可以为空。该表中还有其他几列(我试图省略不相关的信息),其中包括人口中出生的每个人的一行。许多动物出生后不久就死了,因此从来没有人给它们起过名字。我尝试了一下这个查询,它给了我一些小错误,我能够修复它们。子查询需要一个“groupby B.name”,最后的“groupby”需要我包含SQ.gdnas和SQ.wgas。但一旦我添加了这些,它就成功了!谢谢@杰克:对不起,我本应该发现常见的“模棱两可的分组方式”问题,但很容易解决。你可以在Tom的答案旁边接受答案。我已经纠正了分组方式的问题。谢谢你指出这一点。