5

我有三个相关表“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';

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

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

例如,如果我有数据:

一个

id   val
1    something
2    somethingelse

id   val
1    foo
2    bar

AB

aid  bid  val
1    1    3
1    2    2
2    1    1
2    2    4

我只想选择 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'

但这并不完全奏效。首先,它只是感觉是错误的方法,其次,它返回了错误的投标值。也就是说,从子查询返回的出价不一定与 max(val) 来自同一行。我相信这是一个已知的分组问题,当未为排序规则或分组指定列时选择返回的值未定义。

我希望上面的一些内容是有道理的,在过去的几个小时里,我一直在把头撞在墙上,任何帮助都将不胜感激。谢谢。

(对于那些想知道的人,它的实际用途是用于字典后端,其中 A 是单词表,B 是音素表。AB 是带有“位置”列的单词表。查询是查找所有以结尾的单词一个指定的音素。(音素是一个词的声音,在用法上类似于国际音标)

4

5 回答 5

2

我认为您需要先进行另一个联接才能获得每个 a.id 的 ab 的最大 val。

像这样的东西:

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'
于 2008-10-21T04:54:33.437 回答
1

这是我刚刚测试的另一种方法:

select a.*
from ab
   inner join b on(ab.bid=b.id)
   inner join a on (ab.aid=a.id)
where ab.val = (select max(val) from ab AS ab2 where ab2.aid = ab.aid)
   and b.val='foo'
于 2008-10-21T05:08:21.757 回答
1

我经常使用以下技巧来获得最大的每组:

SELECT a.*
FROM ab AS ab1
  LEFT OUTER JOIN ab AS ab2 ON (ab1.aid = ab2.aid AND ab1.val < ab2.val)
  JOIN a ON (ab1.aid = a.id)
  JOIN b ON (ab1.bid = b.id)
WHERE ab2.aid IS NULL
  AND b.val = 'foo';

诀窍是在外部连接中将 AB 表连接到自身。返回 ab1,其中不存在具有相同的辅助值和更大的值的行。因此,对于给定的帮助值,ab1 具有每组行的最大 val。

于 2008-10-21T06:10:27.060 回答
0
SELECT *
FROM
(
  SELECT
    A.*,
    (SELECT top 1 AB.BID FROM AB WHERE A.AID = AB.AID ORDER BY AB.val desc) as BID
  FROM A
) as Aplus
JOIN B ON Aplus.BID = B.BID
于 2008-10-21T14:22:04.243 回答
0

我不确定您使用的是哪个 sql,但是在 MS SQL 中,我创建了一个表值数据库函数来返回表 A 中的最大值,然后将其连接到表 B。当我回顾时,我发现这比复杂的连接更容易理解在稍后阶段我的查询。

于 2008-10-21T11:43:49.900 回答