首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Join做不到,子查询很烂,然后呢?

Join做不到,子查询很烂,然后呢?
EN

Stack Overflow用户
提问于 2009-11-22 07:42:37
回答 2查看 338关注 0票数 2

首先,对于非描述性的标题,我很抱歉,我太匆忙了,所以我想不出一个更好的标题。

第二:

我有一部分数据库,如下图所示:

我在系统上有贡献者,每个人都给许多源写信,一个源可以有许多工作贡献者。用户可以随心所欲地订阅任意数量的贡献者,也可以订阅他们喜欢的多少源。现在,我想做的只是为特定用户检索所有文章。这些文章要么是通过贡献者,要么是用户订阅的源。为了简单起见,当用户订阅某个源时,我只需将所有源贡献者复制到users_contributors表中即可。一个棘手的问题是,当我检索用户的文章时,我会检索他的贡献者所写的所有文章,以及所有在他所遵循的源代码中发表的文章,而这些文章在系统中没有有效的贡献者。(即contributorID为null)。

我创建了以下查询:

代码语言:javascript
复制
 Select Articles.ArticleID, Articles.ContributorId, Contributors.Name, 
    Sources.Name, Articles.ArticleTitle
From Articles 
            Inner Join Contributors On Articles.ContributorId = Contributors.ContributorId
            Inner Join Sources On Articles.SourceId = Sources.SourceID          
Where Articles.ContributorId in (
    Select ContributorId from Users_Contributors
    Where UserID = 3
    )
    OR (

        Articles.SourceId in (
            Select SourceId from Users_Sources
            Where UserID = 3
            )

            and 
            Articles.ContributorId is null
    )

上面的查询的问题是,它不返回任何带有contributorID null的文章。我理解这是因为贡献者表上的联接。在这种情况下我该怎么办?

  1. Should i考虑去规范化吗?
  2. What是每个表上要快速运行的检验字段(罗塞特返回的10000)?
  3. I大约需要在这个查询上支持分页,"With { }“子句对我是合适的,还是应该考虑另一个strategy?

)。

提前谢谢。

Ps:我正在使用Server 2008

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-11-22 08:03:38

代码语言:javascript
复制
SELECT  a.*, s.Name AS SourceName, NULL AS ContributorName
FROM    User_Sources us
JOIN    Articles a
ON      a.SourceID = us.SourceID
JOIN    Source s
ON      s.SourceID = us.SourceID
WHERE   us.UserID = 3
        AND a.ContributorID IS NULL
UNION
SELECT  a.*, s.Name AS SourceName, c.Name AS ContributorName
FROM    User_Contributor uc
JOIN    Articles a
ON      a.ContributorID = uc.ContributorID
JOIN    Contirbutors c
ON      c.ContributorID = uc.ContributorID
JOIN    Sources s
ON      s.SourceID = a.SourceID
WHERE   uc.UserID = 3

如果需要分页,请使用此方法(将页面从80获取到100):

代码语言:javascript
复制
WITH    q AS (
        SELECT  TOP 100 
                a.*, s.Name AS SourceName, NULL AS ContributorName
        FROM    User_Sources us
        JOIN    Articles a
        ON      a.SourceID = us.SourceID
        JOIN    Source s
        ON      s.SourceID = us.SourceID
        WHERE   us.UserID = 3
                AND a.ContributorID IS NULL
        ORDER BY
                OrderDate
        UNION
        SELECT  TOP 100
                a.*, s.Name AS SourceName, c.Name AS ContributorName
        FROM    User_Contributor uc
        JOIN    Articles a
        ON      a.ContributorID = uc.ContributorID
        JOIN    Contirbutors c
        ON      c.ContributorID = uc.ContributorID
        JOIN    Sources s
        ON      s.SourceID = a.SourceID
        WHERE   uc.UserID = 3
        ORDER BY
                OrderDate
        ),
        page AS
        (
        SELECT  TOP 100 *, ROW_NUMBER() OVER (ORDER BY OrderDate) AS rn
        FROM    q
        )
SELECT  *
FROM    page
WHERE   rn >= 80
票数 4
EN

Stack Overflow用户

发布于 2009-11-22 07:52:10

你为什么不让这个加入

代码语言:javascript
复制
Inner Join Contributors On Articles.ContributorId = Contributors.ContributorID

一个外接?

代码语言:javascript
复制
Left Join Contributors On Articles.ContributorId = Contributors.ContributorID

这将导致它返回所有文章,无论是否存在匹配的SourceID (包括ContributorID为空的情况)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1778122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档