Mysql 其中(集合)在(集合)中

Mysql 其中(集合)在(集合)中,mysql,sql,Mysql,Sql,编辑:我似乎问错了这个问题 我试图找到一种方法来查询一个集合在另一个集合中是否可用。例如: SELECT * FROM something WHERE (1, 3) IN (1, 2, 3, 4, 5) SELECT * FROM something WHERE (1, 3) IN (1, 5, 7, 9); 在这种情况下,1和3在集合中(1、2、3、4、5)。另一个例子: SELECT * FROM something WHERE (1, 3) IN (1, 2, 3, 4, 5) SE

编辑:我似乎问错了这个问题

我试图找到一种方法来查询一个集合在另一个集合中是否可用。例如:

SELECT * FROM something
WHERE (1, 3) IN (1, 2, 3, 4, 5)
SELECT * FROM something
WHERE (1, 3) IN (1, 5, 7, 9);
在这种情况下,1和3在集合中(1、2、3、4、5)。另一个例子:

SELECT * FROM something
WHERE (1, 3) IN (1, 2, 3, 4, 5)
SELECT * FROM something
WHERE (1, 3) IN (1, 5, 7, 9);
在这种情况下,1和3不在集合(1、5、7、9)中,因此不应从表中提取任何内容

你可以用这个

SELECT u.* 
FROM users u
INNER JOIN completed_levels cl
ON cl.user_id = u.id
WHERE cl.id IN (1, 5, 7);
或者使用@DanFromGermany中的
EXISTS
,您可以使用此

SELECT u.* 
FROM users u
INNER JOIN completed_levels cl
ON cl.user_id = u.id
WHERE cl.id IN (1, 5, 7);

或者使用
EXISTS
从@DanFromGermany开始

您可以使用
Case
生成一个
总和
,该总和将在1、5和7内的每个级别增加1

SELECT A.* FROM users AS
INNER JOIN 
(
SELECT U.id, 
SUM(CASE WHEN 
      (
         A.completed_levels = 1 
         OR A.completed_levels = 5 
         OR A.completed_levels = 7
      ) THEN 1 ELSE 0 END
   ) AS RN
FROM completed_levels A
INNER JOIN users U ON A.user_id = U.id
GROUP BY U.id
) B ON A.id = B.id 
WHERE B.RN = 3 -- Those users have completed level 1, 5 & 7 will have RN = 3 only

您可以使用
Case
生成一个
Sum
,该值将在1、5和7内的每个级别增加1

SELECT A.* FROM users AS
INNER JOIN 
(
SELECT U.id, 
SUM(CASE WHEN 
      (
         A.completed_levels = 1 
         OR A.completed_levels = 5 
         OR A.completed_levels = 7
      ) THEN 1 ELSE 0 END
   ) AS RN
FROM completed_levels A
INNER JOIN users U ON A.user_id = U.id
GROUP BY U.id
) B ON A.id = B.id 
WHERE B.RN = 3 -- Those users have completed level 1, 5 & 7 will have RN = 3 only

您将
IN
子句与相关子查询一起使用(即子查询引用
u.id
)。这不是我们使用它的方式。子句中的
非常适合非相关子查询;如果需要相关子查询,请改用
EXISTS
。对于您的问题,一个不相关的子查询就足够了,因此请相应地在
中使用

select *
from users
where u.id in (select user_id from completed_levels where id in (1, 5, 7);
如果用户必须具有所有级别:

通过聚合通常可以更好地解决此类问题,这样就不必反复查询同一个表:

select *
from users
where u.id in 
(
  select user_id 
  from completed_levels where id in (1, 5, 7)
  group by user_id
  having count(distinct id) = 3
);

您将
IN
子句与相关子查询一起使用(即子查询引用
u.id
)。这不是我们使用它的方式。
子句中的
非常适合非相关子查询;如果需要相关子查询,请改用
EXISTS
。对于您的问题,一个不相关的子查询就足够了,因此请相应地在
中使用

select *
from users
where u.id in (select user_id from completed_levels where id in (1, 5, 7);
如果用户必须具有所有级别:

通过聚合通常可以更好地解决此类问题,这样就不必反复查询同一个表:

select *
from users
where u.id in 
(
  select user_id 
  from completed_levels where id in (1, 5, 7)
  group by user_id
  having count(distinct id) = 3
);

注意:这回答了原始问题,这似乎与OP修改后的问题无关

您可以使用以下方法获取完成所有三个级别的用户:

SELECT cl.user_id
FROM completed_levels cl
WHERE cl.id IN (3, 5, 7)
GROUP BY cl.user_id
HAVING COUNT(DISTINCT cl.id) = 3;
(注意:
DISTINCT
如果给定用户的ID是唯一的,则不需要。)

然后,您可以使用
连接
或类似构造获得所需:

SELECT u.*
FROM users u JOIN
     (SELECT cl.user_id
      FROM completed_levels cl
      WHERE cl.id IN (3, 5, 7)
      GROUP BY cl.user_id
      HAVING COUNT(DISTINCT cl.id) = 3
     ) cu
     ON cl.user_id = u.id;

注意:这回答了原始问题,这似乎与OP修改后的问题无关

您可以使用以下方法获取完成所有三个级别的用户:

SELECT cl.user_id
FROM completed_levels cl
WHERE cl.id IN (3, 5, 7)
GROUP BY cl.user_id
HAVING COUNT(DISTINCT cl.id) = 3;
(注意:
DISTINCT
如果给定用户的ID是唯一的,则不需要。)

然后,您可以使用
连接
或类似构造获得所需:

SELECT u.*
FROM users u JOIN
     (SELECT cl.user_id
      FROM completed_levels cl
      WHERE cl.id IN (3, 5, 7)
      GROUP BY cl.user_id
      HAVING COUNT(DISTINCT cl.id) = 3
     ) cu
     ON cl.user_id = u.id;
新请求(根据sqlfiddle.com/#!9/f36d92/2):

# The goal is to write a query that will select all exercises # that the user has the correct equipment for, where the pre-defined # set is the id's of the equipment the user has. # For example, let's assume the user has equipment (1, 4) # The exercise "Curls" should be pulled from the table, as the user has all # of the required equipment based on the exercise_requirements table. # while "Wrecking Ball" is not returned as the user only has a portion of the # required equipment. # If the user's equipment was (1, 3, 4) then both "Curls" and "Wrecking ball" # would be returned from the exercises table, as the user has the required equipment # for both exercises. #---- #Below is my take on your query. 解决方案:

# The goal is to write a query that will select all exercises # that the user has the correct equipment for, where the pre-defined # set is the id's of the equipment the user has. # For example, let's assume the user has equipment (1, 4) # The exercise "Curls" should be pulled from the table, as the user has all # of the required equipment based on the exercise_requirements table. # while "Wrecking Ball" is not returned as the user only has a portion of the # required equipment. # If the user's equipment was (1, 3, 4) then both "Curls" and "Wrecking ball" # would be returned from the exercises table, as the user has the required equipment # for both exercises. #---- #Below is my take on your query. 你在这里混淆了一些ID。这将更接近:

SELECT ex.* FROM exercises ex
WHERE ex.id IN (
  SELECT exercise_id FROM exercise_requirements
  WHERE equipment_id IN (1, 4)
  GROUP BY exercise_id
  HAVING COUNT(distinct equipment_id) = 2
);
但这个问题仍然是相反的。我们不想知道是否所有用户的设备都在一套练习所需的设备中,但是否在用户的设备中找到了一套练习所需的设备

可能最简单的编写方法是:根据
练习id
汇总
练习id
要求,并检查用户是否不需要
设备id

select * 
from exercises
where id in
(
  select exercise_id
  from exercise_requirements
  group by exercise_id
  having sum(equipment_id not in (1, 4)) = 0
);
您更新的小提琴:

新请求(根据sqlfiddle.com/#!9/f36d92/2):

# The goal is to write a query that will select all exercises # that the user has the correct equipment for, where the pre-defined # set is the id's of the equipment the user has. # For example, let's assume the user has equipment (1, 4) # The exercise "Curls" should be pulled from the table, as the user has all # of the required equipment based on the exercise_requirements table. # while "Wrecking Ball" is not returned as the user only has a portion of the # required equipment. # If the user's equipment was (1, 3, 4) then both "Curls" and "Wrecking ball" # would be returned from the exercises table, as the user has the required equipment # for both exercises. #---- #Below is my take on your query. 解决方案:

# The goal is to write a query that will select all exercises # that the user has the correct equipment for, where the pre-defined # set is the id's of the equipment the user has. # For example, let's assume the user has equipment (1, 4) # The exercise "Curls" should be pulled from the table, as the user has all # of the required equipment based on the exercise_requirements table. # while "Wrecking Ball" is not returned as the user only has a portion of the # required equipment. # If the user's equipment was (1, 3, 4) then both "Curls" and "Wrecking ball" # would be returned from the exercises table, as the user has the required equipment # for both exercises. #---- #Below is my take on your query. 你在这里混淆了一些ID。这将更接近:

SELECT ex.* FROM exercises ex
WHERE ex.id IN (
  SELECT exercise_id FROM exercise_requirements
  WHERE equipment_id IN (1, 4)
  GROUP BY exercise_id
  HAVING COUNT(distinct equipment_id) = 2
);
但这个问题仍然是相反的。我们不想知道是否所有用户的设备都在一套练习所需的设备中,但是否在用户的设备中找到了一套练习所需的设备

可能最简单的编写方法是:根据
练习id
汇总
练习id
要求,并检查用户是否不需要
设备id

select * 
from exercises
where id in
(
  select exercise_id
  from exercise_requirements
  group by exercise_id
  having sum(equipment_id not in (1, 4)) = 0
);

您更新的小提琴:

这似乎是在问同样的问题,并已在今天早些时候解决-这似乎是在问同样的问题,并已在今天早些时候解决-这不起作用,这将返回所有已完成级别1、5或7的用户。查询需要选择已完成级别1、5和7的用户。这不起作用,将返回已完成级别1、5或7的所有用户。查询需要选择已完成级别1、5和7的用户。我似乎问错了这个问题。我的问题实际上是如何确保一个集合的所有部分都包含在另一个集合中。例如<代码>其中(1,2,3,4,5,6,7)中的(1,5)
为真,而
其中(1,5)中的(1,2,4,7,8)
为假。查询需要动态构造,所以我试图避免大量的
调用。我似乎问错了这个问题。我的问题实际上是如何确保一个集合的所有部分都包含在另一个集合中。例如<代码>其中(1,2,3,4,5,6,7)中的(1,5)
为真,而
其中(1,5)中的(1,2,4,7,8)
为假。查询需要动态构造,所以我试图避免大量的
调用。我似乎问错了这个问题。我的问题实际上是如何确保一个集合的所有部分都包含在另一个集合中。例如其中(1,2,3,4,5,6,7)中的(1,5)为真,而(1,2,4,7,8)中的(1,5)为假。查询需要动态构造,所以我试图避免大量AND调用。好的,我现在明白了。请查看我的更新答案。请查看我的评论中反映的问题编辑+我想我的上一个问题以及戈登的答案仍然符合你编辑的问题。如果您想知道(1,3)是否都在(1,5,7,9)中,并且不想有两个表达式(
1在(1,5,7,9)中)和3在(1,5,7,9
)中),那么从(1,5,7,9)中选择1和3并计算匹配项(这里您只有