我在这个网站上搜索了几个建议,但我还没有完全掌握我所追求的内容。我怀疑只是一个语法/标点符号问题,我只是缺少。
我使用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”跟踪多年来收集的不同组织的信息,包括以下三列。此表中的某些行代表我们不再拥有的组织样本,但仍然在数据库的其他位置引用,因此“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
总而言之,我正在尝试编写一个将从传记中返回每个名字的查询,并在一列中告诉我我为每个人准备了多少'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
我这样做时没有收到任何错误,但我知道它给我的数字是错的 - 太高了。我认为这与我使用多个连接有关,而且我的连接语法需要改变。
有什么想法吗?
答案 0 :(得分:4)
这些数字太高,因为您加入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 :(得分:1)
我不知道“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)
;