MYSQL使用AND和OR条件查询同一列
我有以下表格:MYSQL使用AND和OR条件查询同一列,mysql,relational-division,Mysql,Relational Division,我有以下表格: Topic Content_Topic Content id_topic topic id_content id_topic id_content content 1 aaaaa 1 2 1 xxxxx 2 bbbbb 1
Topic Content_Topic Content
id_topic topic id_content id_topic id_content content
1 aaaaa 1 2 1 xxxxx
2 bbbbb 1 4 2 yyyyy
3 ccccc 1 5 3 zzzzz
4 ddddd 2 1 4 wwwww
5 eeeee 2 3 5 kkkkk
6 fffff 2 5 6 jjjjj
... 3 3 ...
3 4
3 5
...
我正在尝试运行以下查询,但未获得预期结果:
SELECT content FROM Content_Topic ct
LEFT JOIN Content c ON ct.id_content=c.id_topic
LEFT JOIN Topic t ON ct.id_topic=t.id_topic
WHERE (ct.id_topic=2 OR ct.id_topic=3) AND
ct.id_topic IN (4,7,10) AND
(ct.id_topic=5 OR ct.id_topic=9)
我希望所有内容都有id_主题2,4,5或3,4,5或2,7,5或3,7,5等等。。。我收到了一个无效的结果
我做错了什么?你说的是(2或3)和(4或7或10)和(5或9)
这意味着你永远不会得到任何结果
y = 2 or 3
x = 4, 7 or 10
z = 5 or 9
在那种情况下,不可能使x和y
为真
我会使用表别名引用您的内容主题表3次,这样您就可以使每个条件都起作用,我会使用联接而不是子选择,因为它更快:
SELECT content FROM Content c
INNER JOIN Content_Topic ct1 ON ct1.id_content=c.id_topic AND (ct1.id_topic=2 OR ct1.id_topic=3)
INNER JOIN Content_Topic ct2 ON ct2.id_content=c.id_topic AND (ct2.id_topic IN (4,7,10))
INNER JOIN Content_Topic ct3 ON ct3.id_content=c.id_topic AND (ct3.id_topic=5 OR ct3.id_topic=9)
你说的是(2或3)和(4或7或10)和(5或9)
这意味着你永远不会得到任何结果
y = 2 or 3
x = 4, 7 or 10
z = 5 or 9
在那种情况下,不可能使x和y
为真
我会使用表别名引用您的内容主题表3次,这样您就可以使每个条件都起作用,我会使用联接而不是子选择,因为它更快:
SELECT content FROM Content c
INNER JOIN Content_Topic ct1 ON ct1.id_content=c.id_topic AND (ct1.id_topic=2 OR ct1.id_topic=3)
INNER JOIN Content_Topic ct2 ON ct2.id_content=c.id_topic AND (ct2.id_topic IN (4,7,10))
INNER JOIN Content_Topic ct3 ON ct3.id_content=c.id_topic AND (ct3.id_topic=5 OR ct3.id_topic=9)
我认为你的加入条件有问题-
SELECT content
FROM Content_Topic ct
LEFT JOIN Content c ON ct.id_content=c.id_content
WHERE EXISTS (SELECT 1
FROM Topic T
WHERE T.id_topic = ct.Content_Topic
AND ct.id_topic IN (2, 3))
AND EXISTS (SELECT 1
FROM Topic T1
WHERE T1.id_topic = ct.Content_Topic
AND ct.id_topic IN (4,7,10))
AND EXISTS (SELECT 1
FROM Topic T2
WHERE T2.id_topic = ct.Content_Topic
AND ct.id_topic IN (5, 9))
我认为你的加入条件有问题-
SELECT content
FROM Content_Topic ct
LEFT JOIN Content c ON ct.id_content=c.id_content
WHERE EXISTS (SELECT 1
FROM Topic T
WHERE T.id_topic = ct.Content_Topic
AND ct.id_topic IN (2, 3))
AND EXISTS (SELECT 1
FROM Topic T1
WHERE T1.id_topic = ct.Content_Topic
AND ct.id_topic IN (4,7,10))
AND EXISTS (SELECT 1
FROM Topic T2
WHERE T2.id_topic = ct.Content_Topic
AND ct.id_topic IN (5, 9))
我认为使用聚合和
具有用于筛选的子句会更容易做到这一点:
SELECT c.content
FROM Content c
INNER JOIN Content_Topic ct ON ct.id_content = c.id_content
GROUP BY c.id_content, c.content
HAVING
-- 2, 4, 5
(MAX(c.id_topic = 2) = 1 AND MAX(c.id_topic = 4) = 1 AND MAX(c.id_topic = 5) = 1)
-- 3, 4, 5
OR (MAX(c.id_topic = 3) = 1 AND MAX(c.id_topic = 4) = 1 AND MAX(c.id_topic = 5) = 1)
-- 2, 5, 7
OR (MAX(c.id_topic = 2) = 1 AND MAX(c.id_topic = 5) = 1 AND MAX(c.id_topic = 7) = 1)
-- add more if needed ...
这将为您提供主题2、3和5,或主题3、4和5,或主题2、5和7的所有内容。您可以根据需要使用更多的或条件扩展HAVING
子句
另一件需要注意的事情是,您实际上不需要为该任务引入主题
表(您想要的信息可以在内容_主题
中找到)。我认为,通过聚合和使用
子句进行筛选,这将更容易做到:
SELECT c.content
FROM Content c
INNER JOIN Content_Topic ct ON ct.id_content = c.id_content
GROUP BY c.id_content, c.content
HAVING
-- 2, 4, 5
(MAX(c.id_topic = 2) = 1 AND MAX(c.id_topic = 4) = 1 AND MAX(c.id_topic = 5) = 1)
-- 3, 4, 5
OR (MAX(c.id_topic = 3) = 1 AND MAX(c.id_topic = 4) = 1 AND MAX(c.id_topic = 5) = 1)
-- 2, 5, 7
OR (MAX(c.id_topic = 2) = 1 AND MAX(c.id_topic = 5) = 1 AND MAX(c.id_topic = 7) = 1)
-- add more if needed ...
这将为您提供主题2、3和5,或主题3、4和5,或主题2、5和7的所有内容。您可以根据需要使用更多的或条件扩展HAVING
子句
另一件需要注意的事情是,您实际上不需要为该任务引入主题
表(您想要的信息可以在内容_主题
中找到)。看起来您正在进行一种特殊类型的关系划分。也就是说,您正在查找与一组主题相匹配的内容,其中每个元素都有替换项
不能仅对WHERE
子句中的条件执行此操作,因为该条件一次计算一行。给定的行上没有同时为2、4和5的id\u topic
值
您需要对行集合设置一个条件,这就是关系划分
在你的情况下,我会用连接。通过使用联接,您可以对主题的不同内容行进行三次引用,因此条件可以相互排斥
SELECT c.content
FROM Content c
INNER JOIN Content_Topic ct1
ON c.id_content=ct1.id_content AND ct1.id_topic IN (2,3)
INNER JOIN Content_Topic ct2
ON c.id_content=ct2.id_content AND ct2.id_topic IN (4,7,10)
INNER JOIN Content_Topic ct3
ON c.id_content=ct3.id_content AND ct3.id_topic IN (5,9)
此查询必须将内容与三个主题相匹配。如果它不匹配所有三个,那么查询将不会返回内容
但是这三种方法都有不同的选择。看起来您正在进行一种特殊类型的关系划分。也就是说,您正在查找与一组主题相匹配的内容,其中每个元素都有替换项
不能仅对WHERE
子句中的条件执行此操作,因为该条件一次计算一行。给定的行上没有同时为2、4和5的id\u topic
值
您需要对行集合设置一个条件,这就是关系划分
在你的情况下,我会用连接。通过使用联接,您可以对主题的不同内容行进行三次引用,因此条件可以相互排斥
SELECT c.content
FROM Content c
INNER JOIN Content_Topic ct1
ON c.id_content=ct1.id_content AND ct1.id_topic IN (2,3)
INNER JOIN Content_Topic ct2
ON c.id_content=ct2.id_content AND ct2.id_topic IN (4,7,10)
INNER JOIN Content_Topic ct3
ON c.id_content=ct3.id_content AND ct3.id_topic IN (5,9)
此查询必须将内容与三个主题相匹配。如果它不匹配所有三个,那么查询将不会返回内容
但是这三种方法都有替代方法。如果这种方法不可行,您知道另一种管理方法吗?感谢您的帮助查看我的编辑,了解我认为您需要的内容-它未经测试,如果您想要一个工作示例,请安装SQLFIDLE并提供Content c中的链接。。在=c、 id\u主题
您在哪里找到的?在Content
表中没有id\u主题
字段。这似乎有效,似乎是最好的解决方案。我做了一些更正和更改:ct1.id_content=c.id_topic到ct1.id_content=c.id_content,我添加了一个DISTINCT,因为有重复项。如果确定,并且您修改了您的答案,我接受它作为解决方案。选择DISTINCT(c.id\u content),c.*自ct1上的内容c内部连接内容c主题ct1。id\u content=c.id\u content和(ct1.id\u Topic=2或ct1.id\u Topic=3)内部连接内容c主题ct2。id\u content=c.id\u content=c.id\u content和(4,7,10)中的(ct2.id\u Topic)内部连接内容ct3。id\u content=c.id\u content和(ct3.id\u Topic=9)如果这种方法不可行,您知道另一种管理方法吗?感谢您的帮助查看我的编辑,了解我认为您需要的内容-它未经测试,如果您想要一个工作示例,请安装SQLFIDLE并提供Content c中的链接。。在=c、 id\u主题
您在哪里找到的?在Content
表中没有id\u主题
字段。这似乎有效,似乎是最好的解决方案。我做了一些更正和更改:ct1.id_content=c.id_topic到ct1.id_content=c.id_content,我添加了一个DISTINCT,因为有重复项。如果确定,并且您修改了您的答案,我接受它作为解决方案。选择DISTINCT(c.id\u content),c.*自ct1上的内容c内部连接内容c主题ct1。id\u content=c.id\u content和(ct1.id\u Topic=2或ct1.id\u Topic=3)内部连接内容c主题ct2。id\u content=c.id\u content=c.id\u content和(4,7,10)中的(ct2.id\u Topic)内部连接内容ct3。id\u content=c.id\u content和(ct3.id\u Topic=9)使用联接而不是子选择:使用联接而不是子选择:使用联接而不是子选择:使用联接而不是子选择:此操作有效,但在