postgresql Postgres多个连接

x9ybnkn6  于 2023-10-18  发布在  PostgreSQL
关注(0)|答案(3)|浏览(137)

这是一个postgres db。我试图拉狗品种名称(甘蔗科索,拉布拉多,等)从品种表,显示的基础上位于一个动物表的外键。我的问题是animal表有两个指向这个单一品种表的外键,我的查询总是出错。第一个品种名称将根据左联接返回,但第二个我无法显示名称,因为我已经有了左联接。下面是我正在尝试做的事情的简要概述:

breed table (ID, BreedName)
animal table (ID, breedID, breed2ID)

SELECT animal.ID, breed.BreedName FROM animal LEFT JOIN breed ON animal.breedID=breed.ID WHERE animal.ID='7';

我需要做的是让BreedName加入animal.breed2ID,我在这方面失败得很惨。我可以很容易地对品种名称进行硬编码,并将其显示在应用程序中,但这不利于在数据库中更改、添加或删除品种名称。

z8dt9xmd

z8dt9xmd1#

只需在同一个表上执行另一个连接:

SELECT animal.ID, breed1.BreedName as BreedName1, breed2.BreadName as BreadName2 
FROM animal 
   LEFT JOIN breed as breed1 ON animal.breedID=breed1.ID 
   LEFT JOIN breed as breed2 ON animal.breedID=breed2.ID 
WHERE animal.ID='7';
cig3rfwq

cig3rfwq2#

虽然Ivan已经解决了你当前数据库设计的问题,但一个长期的考虑或者只是一件值得学习的事情是让你的表设计更加规范化,这样每次你想给动物添加一个品种时就不必添加一个新的连接。通过这个简单的设计,你实际上使你的生活更加困难。
当你看到一个实体上重复的属性类型时,在你的例子中是breedID和breed2ID,除了极少数情况外,你通常应该开始闻到一些腐烂的味道。
在理想的设计下,你会做以下事情。
1.保持你的品种。
2.让animal看起来像animal(animal_id,animal_name)。
3.添加新的animal_breed表。它看起来像这个animal_breed(animal_breed_id,animal_id,breed_id)。其中animal_bread_id是pk和(animal_id,breed_id)上的唯一键,外键指向相应的表。
这种设计允许给定的动物采用一个或多个品种类型,而不必扰乱您的查询以返回多个品种。你现在的设计变成了一场噩梦,每次你有一个额外的品种的动物。它有可能降低性能,使维护成为一场噩梦,最重要的是它不是合理的数据库设计。

ldioqlga

ldioqlga3#

要避免多个连接,请执行具有多个条件的单个连接:

SELECT a.ID, b.ID, b.BreedName
FROM animal a
JOIN breed b
ON b.ID = a.breedID OR b.ID = a.breed2ID
WHERE a.ID='7';

为什么是JOIN而不是LEFT JOIN

  • 假设您不需要animal表中的所有记录(有或没有匹配),您可以使用默认(内部)连接而不是左连接来仅检索匹配的行。

有没有其他解决办法?

  • 使用IN代替ORJOIN breed ON b.id IN (a.breedID, a.breed2ID)-考虑到只有2个id,这可能是可以忽略的,但你需要检查执行计划,看看哪一个更快。

还有其他意见吗

  • 看到这两个外键(breedIDbreed2ID)没有约束,可能会有重复的品种结果。如果你想要独特的品种记录,你可以使用GROUP BYDISTINCT

相关问题