【发布时间】:2017-03-28 11:31:55
【问题描述】:
假设我有两张桌子,例如:
+-----------------------------+
|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 中获取满足b 中的一组条件的行,其中可能有多行。
例如:
获取具有
b_value一个和其他b_value两个的任何人的名字和姓氏。在示例数据中,这仅指马特达蒙。获取具有三个
b_value或四个b_value的任何人的名字和姓氏。在示例数据中,Ryan Gosling 的b_value为 3,Tom Cruise 的b_value为 4,因此 Ryan Gosling 和 Tom Cruise 都会返回。-
获取以下任何人的名字和姓氏:
- 一个
b_value和另一个b_value两个。 -
b_value三个。
- 一个
在示例数据中,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子句不使用索引,因此查询速度明显变慢。
我是否应该采用不同的方法来执行此类查询,请记住,我并没有真正直接控制用于过滤的条件。
【问题讨论】:
-
能否请您添加最终结果应该是什么。目前还不清楚。同样在您的第二个示例中,您说 b_value 是三或四,它应该返回 Ryan Gosling 和 Tom Cruise。如果您在第一部分中指定 OR,那么我想您不能在第二部分中使用 AND,除非我遗漏了什么。
-
@Kevin 我已经稍微更新了这个问题,希望能澄清一些事情
-
在您的示例中,您指定了 3 个示例,我想还有其他可能的过滤方式吗?我几乎会建议使用动态 sql。我也猜过滤器是由用户制作的?也许你可以在应用程序中准备你的 where 子句,传递一个变量并将它放在你的动态 sql 语句中执行。
-
@Kevin 是的,没错。抱歉,我以为这是暗示的-我的错。那条动态 sql 语句会是什么样子?
标签: mysql sql group-by inner-join having