我们说我有两张桌子,比如:
+-----------------------------+
|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 |
+------+------+---------+
我希望能够SELECT
a
行满足b
中可能有多行的b_value
标准。{/ p>
例如:
获取b_value
个{和} b_value
的任何人的名字和姓氏。在示例数据中,这仅指Matt Damon。
获取b_value
为三个,或b_value
为四的任何人的名字和姓氏。在示例数据中,Ryan Gosling有三个b_value
,而Tom Cruise有四个b_value
,所以Ryan Gosling和Tom Cruise都会被退回。
获取具有以下任何一个的人的名字和姓氏:
b_value
一个b_value
两个。{/ li>
HAVING
。在示例数据中,Matt Damon遇到了第一个条件,而Ryan Gosling遇到了第二个条件,因此两者都返回了。
困难来自于这些条件复杂,多个和/或条件组合以及长度变量。
我目前的尝试(在这种情况下具体解决了示例3),正在使用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
有很多行。 $("#addfield").click(function(){
alert($(this).data('id')+1);
$(this).data('id', + $('#addfield').data('id')+1);
console.log($(this).data('id'));
})
子句不使用索引,因此查询速度非常慢。我是否应采取不同的方法来进行此类查询,同时牢记我并非真正直接控制用于过滤的条件。
答案 0 :(得分:0)
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)
答案 1 :(得分:0)
SELECT rows from a where it has b_value of both one and two would return Matt Damon.
如果你想要上面的结果那么表" a" " ID"列应该有唯一的记录, 表a和b都应该有主键。
或者您可以尝试以下查询,但它会返回" matt守护程序"
的双重记录select firstname,lastname from a left join b on a.a_id=b.a_id ;
答案 2 :(得分:0)
在动态SQL中,它会像这样,首先我建议在应用程序中创建一个变量,根据过滤器的选择填充
- var exampleOne = "(b_value = 'one') OR (b_value = 'two')";
- var exampleTwo = "(b_value = 'three') OR (b_value = 'four')";
- var exampleThree = "(b_value = 'one' or b_value = 'two') OR (b_value = 'three')"
然后,您可以使用一个参数创建存储过程,在此处传递变量
CREATE PROCEDURE `spNames`(IN whereFilter VARCHAR(255))
BEGIN
SET @SqlText = CONCAT('SELECT DISTINCT a.firstname, a.lastname
FROM @a AS a INNER JOIN @b AS b ON a.a_id=b.a_id
WHERE ', whereFilter);
PREPARE stmt FROM @SqlText;
EXECUTE stmt;
DEALLOCATE PREPARE stmt
END
然后,您可以从代码中调用此存储过程并传入变量
CALL spNames (exampleOne);