我有两个课:问题和用户。 Question类有一个名为category_ids
的{{1}}类型的字段,而User类有一个对象Column(ARRAY(Integer))
,它有一个名为preferences
的字段,类型为{{ 1}}。
我正在尝试从用户首选项中查询ignored_categories
字段中显示的Column(ARRAY(Integer))
字段中至少没有一个值的所有问题,或者如果前一个为真,那么category_ids
字段中不在用户首选项字段ignored_categories
中的其他值。因此,以下情况应该如此:
category_ids
= []和ignore_categories
= [1,2,3] =>应该通过。category_ids
= [1,2,4]和ignored_categories
= [1,2,3] =>应该通过。category_ids
= [1]和ignored_categories
= [1,2,3] =>应该忽略。category_ids
= [1,2,3]和ignored_categories
= [1,2,3] =>应该忽略。category_ids
= [1,2,3,4]和ignored_categories
= [1,2,3] =>应该通过。category_ids
= [5,7]和ignored_categories
= [1,2,3] =>应该通过。这是我到目前为止所提出的:
category_ids
问题是ignored_categories
仅测试user = DBSession.query(User).filter_by(id=user_id).one() # this gets the user object
query = DBSession.query(Question).order_by(Question.created_at.desc())
query = query.filter(
or_(
not_(
Question.category_ids.overlap(user.preferences.ignored_categories)
),
Question.category_ids.contains(user.preferences.ignored_categories)
)
)
是contains
的超集,这无法为数据集提供正确的结果,例如:
category_ids
= [1]和ignored_categories
= [1,2,3] =>应该忽略。因此,它需要另一个条件来测试是否存在至少一个匹配的值,而没有其他值不匹配。
category_ids
函数仅测试两个数组中是否存在至少一个值,但是这样的测试失败,例如:
ignored_categories
= [1,2,4]和overlap
= [1,2,3] =>应该通过。哪个应该通过,但它没有,因为我需要否定操作。如果我不否定它,它只会过滤掉绝对没有共同点的数组。
编辑:这是我的表格的样子:
category_ids
答案 0 :(得分:0)
这个问题相当于category_ids
中找不到ignored_categories
中不存在的元素,特殊情况是如果category_ids
为空,则不会被忽略。
这可以通过连接表完成,如下所示:
SELECT DISTINCT questions.*
FROM questions
LEFT JOIN question_categories ON questions.id = question_categories.question_id
WHERE (
question_categories.category_id IS NULL -- special case where question has no categories
OR question_categories.category_id NOT IN (
SELECT category_id FROM user_ignored_categories WHERE user_id = 123 -- for this user
) -- find a category that isn't ignored
)
要使用数组执行此操作,您可以执行以下操作:
SELECT questions.*
FROM questions
WHERE (
cardinality(categories) = 0 -- special case where question has no categories
OR NOT ((SELECT ignored_categories FROM users WHERE id = 123) @> categories)
);
您可以针对您的数据here测试这些内容。