选择跨多行sqlite的匹配
Selecting a match across multiple rows sqlite
假设我有一个名为 food_prefs
的 table 朋友和他们最喜欢的食物。
id
name
favorite_foods
1
Amy
Pizza
2
Bob
Pizza
3
Chad
Caviar
4
Dana
Pizza
5
Dana
Salad
我知道如何获取所有喜欢披萨的人的名字,但我不清楚如何select 只将 pizza
列为他们最喜欢的食物的人。即从上面table,我只想selectAmy和Bob
此外,如果有一个解决方案也可以 select 具有多个收藏夹的名称(例如,在另一个查询中 select 每个喜欢 pizza and salad
的人,这将是很棒的将)。最后,如果 pizza and salad
查询不仅返回只喜欢两种食物的人,而且还返回只喜欢列表中出现的一种食物的人(例如只喜欢披萨或沙拉的人——每个人),这可能会很有用但在这个例子中是乍得)
(我发现 sqlite 文档不是最简单的,如果这是一个非常简单的问题,我很抱歉!)
你是对的(正如我在你的问题下方的评论中读到的那样),根据你的要求,你需要聚合和 HAVING
子句中的条件。
例如,要让 只有 的人将 'pizza' 列为他们最喜欢的食物:
SELECT name
FROM food_prefs
GROUP BY name
HAVING GROUP_CONCAT(favorite_foods) = 'Pizza';
但是如果你想让只有的人将'pizza'和'salad'列为他们最喜欢的食物,这个:
HAVING GROUP_CONCAT(favorite_foods) = 'Pizza,Salad'
可能行不通,因为SQLite不支持函数GROUP_CONCAT()
中的ORDER BY
子句,所以不保证会return'Pizza,Salad'
(它也可以 return 'Salad,Pizza'
).
在这种情况下,您需要一个更复杂的 HAVING
子句:
HAVING SUM(favorite_foods IN ('Pizza', 'Salad')) = 2
AND SUM(favorite_foods NOT IN ('Pizza', 'Salad')) = 0
或:
HAVING SUM(favorite_foods IN ('Pizza', 'Salad')) = 2
AND COUNT(*) = 2
我假设 name
和 favorite_foods
的组合是唯一的。
对于将 'pizza' and/or 'salad' 列为他们最喜欢的食物,但他们也可能有其他食物的人列出,你只需要一个 WHERE
子句而不是聚合:
SELECT DISTINCT name
FROM food_prefs
WHERE favorite_foods IN ('Pizza', 'Salad');
(此处为 OP)EXCEPT
似乎可以解决问题:
SELECT name
FROM food_prefs
WHERE favorite_foods in ('pizza', 'salad')
EXCEPT
SELECT name
FROM food_prefs
WHERE favorite_foods not in ('pizza', 'salad')
根据我的理解,它会选择所有在我们的选项列表中有最喜欢的食物的 name
s,然后删除所有在该列表之外有最喜欢的 name
s(在上面的例子,('pizza', 'salad')
).
假设我有一个名为 food_prefs
的 table 朋友和他们最喜欢的食物。
id | name | favorite_foods |
---|---|---|
1 | Amy | Pizza |
2 | Bob | Pizza |
3 | Chad | Caviar |
4 | Dana | Pizza |
5 | Dana | Salad |
我知道如何获取所有喜欢披萨的人的名字,但我不清楚如何select 只将 pizza
列为他们最喜欢的食物的人。即从上面table,我只想selectAmy和Bob
此外,如果有一个解决方案也可以 select 具有多个收藏夹的名称(例如,在另一个查询中 select 每个喜欢 pizza and salad
的人,这将是很棒的将)。最后,如果 pizza and salad
查询不仅返回只喜欢两种食物的人,而且还返回只喜欢列表中出现的一种食物的人(例如只喜欢披萨或沙拉的人——每个人),这可能会很有用但在这个例子中是乍得)
(我发现 sqlite 文档不是最简单的,如果这是一个非常简单的问题,我很抱歉!)
你是对的(正如我在你的问题下方的评论中读到的那样),根据你的要求,你需要聚合和 HAVING
子句中的条件。
例如,要让 只有 的人将 'pizza' 列为他们最喜欢的食物:
SELECT name
FROM food_prefs
GROUP BY name
HAVING GROUP_CONCAT(favorite_foods) = 'Pizza';
但是如果你想让只有的人将'pizza'和'salad'列为他们最喜欢的食物,这个:
HAVING GROUP_CONCAT(favorite_foods) = 'Pizza,Salad'
可能行不通,因为SQLite不支持函数GROUP_CONCAT()
中的ORDER BY
子句,所以不保证会return'Pizza,Salad'
(它也可以 return 'Salad,Pizza'
).
在这种情况下,您需要一个更复杂的 HAVING
子句:
HAVING SUM(favorite_foods IN ('Pizza', 'Salad')) = 2
AND SUM(favorite_foods NOT IN ('Pizza', 'Salad')) = 0
或:
HAVING SUM(favorite_foods IN ('Pizza', 'Salad')) = 2
AND COUNT(*) = 2
我假设 name
和 favorite_foods
的组合是唯一的。
对于将 'pizza' and/or 'salad' 列为他们最喜欢的食物,但他们也可能有其他食物的人列出,你只需要一个 WHERE
子句而不是聚合:
SELECT DISTINCT name
FROM food_prefs
WHERE favorite_foods IN ('Pizza', 'Salad');
(此处为 OP)EXCEPT
似乎可以解决问题:
SELECT name
FROM food_prefs
WHERE favorite_foods in ('pizza', 'salad')
EXCEPT
SELECT name
FROM food_prefs
WHERE favorite_foods not in ('pizza', 'salad')
根据我的理解,它会选择所有在我们的选项列表中有最喜欢的食物的 name
s,然后删除所有在该列表之外有最喜欢的 name
s(在上面的例子,('pizza', 'salad')
).