给出这些表:
id_article | title
1 | super article
2 | another article
id_tag | title
1 | great
2 | awesome
id_relation | id_article | id_tag
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
我希望能够选择所有“很棒”和“很棒”的文章(最终,我可能也必须实现OR)
基本上,如果我对article进行选择,那么连接到id_article的关系表:当然,我不能连接id_tag的两个不同值。我只有将ID串联起来才能测试为字符串,但这似乎很la脚,必须有一个更漂亮的解决方案。
哦,如果重要的话,我使用MySQL服务器。
编辑:对于ByWaleed,典型的sql select肯定会失败,而我在原始问题中引用了它:
SELECT
a.id_article,
a.title
FROM articles a, relations r
WHERE
r.id_article = a.id_article and r.id_tag = 1 and r.id_tag = 2
将无法工作,因为r.id_tag在同一行上显然不能为1和2。我怀疑w3schools上有一篇文章。我在Google上的搜索未产生任何结果,可能是因为我搜索了错误的关键字。
答案 0 :(得分:2)
如果您照常进行所有联接,然后按文章将行汇总到一组,则可以断言它们必须至少具有两个不同的标签。
(已经过滤到great
和/或awesome
,这意味着它们同时具有。)
SELECT
a.id_article,
a.title
FROM
articles a
INNER JOIN
relations r
ON r.id_article = a.id_article
INNER JOIN
tags t
ON t.id_tag = r.id_tag
WHERE
t.title IN ('great', 'awesome')
GROUP BY
a.id_article,
a.title
HAVING
COUNT(DISTINCT t.id_tag) = 2
(DISTINCT
是为了避免一篇文章有两次'great'
的可能性。)
要执行OR
,只需删除HAVING
子句。
答案 1 :(得分:1)
一种方法是按文章进行汇总,然后断言文章同时具有“ great”标签和“ awesome”标签:
SELECT
a.id_article,
a.title
FROM articles a
INNER JOIN relations r
ON a.id_article = r.id_article
INNER JOIN tags t
ON r.id_tag = t.id_tag
WHERE
t.title IN ('great', 'awesome')
GROUP BY
a.id_article,
a.title
HAVING
MIN(t.title) <> MAX(t.title);
这里的逻辑是,我们首先将每篇文章的记录限制为仅两个目标标签的记录。然后,我们断言在HAVING
子句中,同时出现两个 标签。我在这里使用了MIN
/ MAX
技巧,因为如果min和max不同,则意味着存在两个不同的标签。
答案 2 :(得分:1)
步骤1:使用临时表获取所有带有标题的文章。
第2步:如果一篇文章在您的临时表中多次出现,则意味着它的标题很棒。
尝试:
CREATE TEMPORARY TABLE MyTempTable (
select t1.id_article, t2.title
from table1 t1
inner join table3 t3 on t3.id_article = t1.id_article
inner join table2 t2 on t2.id_tag = t3.id_tag
)
select m.id_article
from MyTempTable m
group by m.id_article
having count(*)>1
编辑:此解决方案假定有两个可能的标签,很棒和很棒。如果更多,请在选择查询中添加“ where”子句以创建临时表,例如where t2.title in ('great','awesome')