有趣的多对多sql连接
我有三个相关表“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 对的最大值时才返回行
。 如果我有数据:
A
id val
1 something
2 somethingelse
B
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'
但这不太有效。 首先,这感觉是错误的方法,其次,它返回了错误的出价。 也就是说,子查询返回的 bid 不一定与 max(val) 来自同一行。 我相信这是一个已知的分组问题,其中未定义未定义未指定列的排序规则或分组时要返回的值的选择。
我希望上面的一些内容是有道理的,在过去的几个小时里,我一直在用头撞墙,任何帮助都将非常感激。 谢谢。
(对于那些想知道的人来说,它的实际用途是用于字典后端,其中 A 是单词表,B 是音素表。AB 是带有“位置”列的 WordPhoneme 表。查询是查找以结尾的所有单词指定的音素(音素是一个单词的发音,用法类似于国际音标)
I have three related tables "A(id, val)", "B(id, val)", and a link table with a value "AB(aid, bid, val)"
I am querying against B to bring back A values, for example:
SELECT A.*
FROM A INNER JOIN AB ON A.id = AB.aid INNER JOIN B ON AB.bid = B.id
WHERE B.val = 'foo';
Every A has many B's and every B has many A's.
And the catch that I'm falling apart on is the need to filter the set so that the query returns rows only when AB.val is a max for any given A/B pair
E.g. if I have the data:
A
id val
1 something
2 somethingelse
B
id val
1 foo
2 bar
AB
aid bid val
1 1 3
1 2 2
2 1 1
2 2 4
I would want to select only the first and last rows of AB since they are the max values for each of the A's and then be able to query against B.val = 'foo' to return only the first row. I don't have a clue on how I can constrain against only the max val row in the AB table.
The best I've been able to get is
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'
but this doesn't quite work. First, it just feels to be the wrong approach, second, it returns bad bid values. That is, the bid returned from the subquery is not necessarily from the same row as the max(val). I believe this is a known group by issue where selection of values to return when the column is not specified for either collation or grouping is undefined.
I hope that some of the above makes sense, I've been banging my head against a wall for the past few hours over this and any help at all would be hugely appreciated. Thanks.
(For those wondering, the actual use of this is for a Dictionary backend where A is the Word Table and B is the Phoneme Table. AB is the WordPhoneme table with a 'position' column. The query is to find all words that end with a specified phoneme. (a phoneme is a word sound, similar in usage to the international phonetic alphabet )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为您需要先进行另一次连接才能获取每个 a.id 的 ab 最大值。
像这样的事情:
I think you need to do another join to get ab's max val for each a.id first.
Something like this:
我经常使用以下技巧来获得每个组中最大的值:
该技巧是通过外连接将 AB 表连接到自身。 如果不存在具有相同 help 值和更大 val 值的行,则返回 ab1。 因此 ab1 具有给定辅助值的每组行的最大 val。
I often use the following trick to get the greatest per group:
The trick is to join to the AB table to itself in an outer join. Return ab1 where no rows exist with the same value for aid and a greater value for val. Therefore ab1 has the greatest val per group of rows with a given value for aid.
这是我刚刚测试过的另一种方法:
Here's another way that I just tested out:
我不确定您使用的是哪个sql,但在MS SQL中,我创建了一个表值数据库函数来返回表A中的最大值,然后将其连接到表B。当我回头看时,我发现这比复杂的连接更容易理解关于我稍后的询问。
I am not sure which sql you are using but in MS SQL I create a table-valued database function to return the max values from table A then join this to table B. I find this much easier to understand than complex joins when I look back on my queries at a later stage.