1

我有以下表格:

news
idNews | title
1      | Title 1
2      | Title 2
3      | Title 3
4      | Title 4

tags
idTag | name
1     | Name_tag1
2     | Name_tag2
3     | Name_tag3
4     | Name_tag4

映射表:

tag_news
idTag | idNews
1     | 1
2     | 1
1     | 2
2     | 2
2     | 3
3     | 3
4     | 3
4     | 4

我想通过给一个 idNews 来获取几乎有一个共同标签的相关新闻的标题。我可以用三个 SELECT 来做到这一点:

SELECT title FROM news WHERE idNews IN 
 (SELECT DISTINCT idNews FROM tag_news 
  WHERE idTag IN 
  (SELECT idTag FROM tag_news WHERE idNews='$idNews'))

其中 $idNews id 是我通过参数给出的 ID。

这很好用,但我想是否有另一种方法来改进查询。

提前致谢, 伊克

4

2 回答 2

6

当您使用 SQL 编程时,您确实需要了解连接。连接是 SQL 的基础,就像 while 循环是大多数其他编程语言的基础一样。

SELECT DISTINCT n.title FROM news n
INNER JOIN tag_news t1 ON t1.idNews = n.idNews
INNER JOIN tag_news t2 ON t1.idTag = t2.idTag
WHERE t2.idNews = $idNews;

从SQL 连接的可视化解释开始


来自@Beth的评论:

我并不是要反驳你,但我很确定我的查询是正确的,它不需要三个连接。以下是它的工作原理:

  • t2tag_newswhere中的行集t2.idNews=$idNews。例如,如果 $idNews=1 那么这将产生以下行:

    idTag | idNews
    1     | 1
    2     | 1
    
  • 从那里,我们希望 tag_news 中与任何相同标签匹配的所有其他行。所以t1.idTag=t2.idTag。这为我们提供了以下行t1.idTag IN (1,2)

    idTag | idNews
    1     | 1
    2     | 1
    1     | 2
    2     | 2
    2     | 3
    
  • 从那里,返回news匹配任何值的所有行t1.idNews。换句话说,在哪里news.idNews IN (1,2,3)

    idNews | title
    1      | Title 1
    2      | Title 2
    3      | Title 3
    
于 2012-11-21T18:19:41.737 回答
2

尝试:

SELECT distinct title 
FROM  
tag_news t1  inner join 
tag_news t2 on
t1.idnews = t2.idnews inner join
tag_news t3 on
t2.idtag = t3.idtag inner join
news n on
n.idnews = t3.idnews
WHERE t1.idNews='$idNews'

抱歉,第一次和第二次错过了:

CREATE TABLE [dbo].news(
    idnews [int] NOT NULL,
    title [varchar](50) NULL
) ON [PRIMARY]

insert into news(idnews, title) values(1,'title 1')
insert into news(idnews, title) values(2,'title 2')
insert into news(idnews, title) values(3,'title 3')
insert into news(idnews, title) values(4,'title 4')

CREATE TABLE [dbo].tag_news(
    idtag [int] NOT NULL,
    idnews [int] NOT NULL,
) ON [PRIMARY]

insert into tag_news(idtag, idnews) values(1,1)
insert into tag_news(idtag, idnews) values(2,1)
insert into tag_news(idtag, idnews) values(1,2)
insert into tag_news(idtag, idnews) values(2,2)
insert into tag_news(idtag, idnews) values(2,3)
insert into tag_news(idtag, idnews) values(3,3)
insert into tag_news(idtag, idnews) values(4,3)
insert into tag_news(idtag, idnews) values(4,4)

select * from news; 
select * from tag_news;

SELECT title FROM news WHERE idNews IN 
 (SELECT DISTINCT idNews FROM tag_news 
  WHERE idTag IN 
  (SELECT idTag FROM tag_news WHERE idNews=1));

SELECT distinct title 
FROM  
tag_news t1  inner join 
tag_news t2 on
t1.idnews = t2.idnews inner join
tag_news t3 on
t2.idtag = t3.idtag inner join
news n on
n.idnews = t3.idnews
WHERE t1.idNews=1;
于 2012-11-21T18:22:40.353 回答