有趣的很多sql加入

5 sql many-to-many inner-join subquery left-join

我有三个相关的表"A(id,val)","B(id,val)",以及一个值为"AB(aid,bid,val)"的链接表

我正在查询B以带回A值,例如:

SELECT A.* 
FROM A INNER JOIN AB ON A.id = AB.aid INNER JOIN B ON AB.bid = B.id
WHERE B.val = 'foo';
Run Code Online (Sandbox Code Playgroud)

每个A有很多B,每个B都有很多A.

我正在崩溃的问题是需要过滤集合,以便只有当AB.val是任何给定A/B对的最大值时,查询才会返回行

例如,如果我有数据:

一个

id   val
1    something
2    somethingelse
Run Code Online (Sandbox Code Playgroud)

id   val
1    foo
2    bar
Run Code Online (Sandbox Code Playgroud)

AB

aid  bid  val
1    1    3
1    2    2
2    1    1
2    2    4
Run Code Online (Sandbox Code Playgroud)

我想只选择AB的第一行和最后一行,因为它们是每个A的最大值,然后能够查询B.val ='foo'以仅返回第一行.我不知道如何仅限制AB表中的max val行.

我能得到的最好的是

SELECT * 
FROM A 
INNER JOIN 
  (SELECT aid, bid, MAX(val) AS val FROM AB GROUP BY aid) as AB
  ON A.id = AB.aid 
INNER JOIN B ON AB.id = B.id
WHERE B.val = 'foo'
Run Code Online (Sandbox Code Playgroud)

但这不太有效.首先,它只是感觉是错误的方法,其次,它返回不良的出价值.也就是说,从子查询返回的出价不一定与max(val)在同一行.我相信这是一个已知的分组问题,其中未指定列进行归类或分组时选择要返回的值是未定义的.

我希望上面的一些有道理,过去几个小时我一直在撞墙,任何帮助都会非常感激.谢谢.

(对于那些想知道的人,实际使用的是字典后端,其中A是Word表,B是音素表.AB是WordPhoneme表,带有'position'列.查询是查找所有以指定的音素.(音素是单词声音,类似于国际拼音字母的使用)

Blo*_*ard 2

我认为您需要再进行一次连接才能首先获取每个 a.id 的 ab 最大值。

像这样的东西:

select a.*
from a
left join (
    select aid, max(val) as val 
    from ab 
    group by aid
) abmax on abmax.aid=a.id
inner join ab on ab.aid=abmax.aid and ab.val=abmax.val
inner join b on b.id=ab.bid
where b.val='foo'
Run Code Online (Sandbox Code Playgroud)