假设我有两个表,例如:
+-----------------------------+
|a |
+------+-----------+----------+
| a_id | firstname | lastname |
+------+-----------+----------+
| 1 | Tom | Cruise |
| 3 | Matt | Damon |
| 4 | Ben | Affleck |
| 8 | Ryan | Gosling |
+------+-----------+----------+
+-----------------------+
| b |
+------+------+---------+
| b_id | a_id | b_value |
+------+------+---------+
| 2 | 3 | one |
| 1 | 3 | two |
| 4 | 8 | three |
| 8 | 1 | four |
+------+------+---------+
我希望能够从 a
中SELECT
行,满足 b
中的一组条件,其中可能有多个行.
例如:
获取
b_value
为 1 且其他b_value
为 2 的任何人的名字和姓氏。在示例数据中,这仅指 Matt Damon。获取
b_value
为三或b_value
为四的任何人的名字和姓氏。在示例数据中,Ryan Gosling 的b_value
为 3,而 Tom Cruise 的b_value
为 4,因此 Ryan Gosling 和 Tom Cruise 都将返回。获取任何人的名字和姓氏:
b_value
为 1,另一个b_value
为 2。b_value
为 3。
在示例数据中,Matt Damon 满足第一个条件,Ryan Gosling 满足第二个条件,因此两者都被返回。
困难来自于这些条件很复杂,组合了多个和/或条件,并且长度可变。
我目前的尝试(在本例中专门解决示例 3)是在 HAVING
中使用聚合函数:
SELECT firstname, lastname
FROM temp_a INNER JOIN temp_b ON temp_a.a_id = temp_b.a_id
GROUP BY temp_a.a_id
HAVING (SUM(b_value="one") AND SUM(b_value="two")) OR SUM(b_value="three");
它得到了正确的行,但是这种方法对我来说有两个直接的问题:
SUM
似乎错误且复杂。我必须找到每个条件并确保每个条件都包含在SUM
中,其中可能有很多。b_value
被索引,b
有很多行。HAVING
子句不使用索引,因此查询速度明显变慢。
我是否应该采用不同的方法来执行此类查询,请记住,我并不能真正直接控制用于过滤的条件。
最佳答案
drop table if exists a,b;
create table a( a_id int, firstname varchar(20), lastname varchar(20));
insert into a values
( 1 , 'Tom' , 'Cruise' ),
( 3 , 'Matt' , 'Damon' ),
( 3 , 'Ben' , 'Affleck'),
( 8 , 'Ryan' , 'Gosling');
create table b( b_id int, a_id int, b_value varchar(20));
insert into b values
( 2 , 3 , 'one' ),
( 1 , 3 , 'two' ),
( 4 , 8 , 'three'),
( 8 , 1 , 'four' );
select firstname, lastname,s.vals
from a
join
(
select b.a_id, group_concat(b_value) vals from b group by b.a_id
) s on a.a_id = s.a_id
where s.vals in ('one,two') or s.vals in ('three')
+-----------+----------+---------+
| firstname | lastname | vals |
+-----------+----------+---------+
| Matt | Damon | one,two |
| Ben | Affleck | one,two |
| Ryan | Gosling | three |
+-----------+----------+---------+
3 rows in set (0.02 sec)
关于MySQL选择连接表中多行的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43068422/