如何使用distinct来连接三个表

时间:2015-03-29 20:08:10

标签: sql sql-server

我试图加入三个表来提取相关资产(图片等)的不同博客帖子列表,但我不断推出一个裁剪器。这三种平板电脑为tblBlogtblAssetLinktblAssets。博客平板电脑持有博客,资产表持有资产,Assetlink表将两者连接在一起。

tblBlog.BID是博客中的PK,tblAssets.AID是资产中的PK。

此查询有效,但会为同一记录拉回多个帖子。我尝试过使用select distinct和group by甚至union,但是因为我对SQL的了解非常差 - 所有这些都是错误的。

我还想对任何标记为已删除的资产(tblAssets.Deleted = true)进行折扣,但不会隐藏相关的博客帖子(如果该帖子未标记为已删除)。如果有人可以提供帮助 - 非常感谢!感谢。

到目前为止我的查询......

SELECT dbo.tblBlog.BID,
       dbo.tblBlog.DateAdded,
       dbo.tblBlog.PMonthName,
       dbo.tblBlog.PDay,
       dbo.tblBlog.Header,
       dbo.tblBlog.AddedBy,
       dbo.tblBlog.PContent,
       dbo.tblBlog.Category,
       dbo.tblBlog.Deleted,
       dbo.tblBlog.Intro,
       dbo.tblBlog.Tags,
       dbo.tblAssets.Name,
       dbo.tblAssets.Description,
       dbo.tblAssets.Location,
       dbo.tblAssets.Deleted AS Expr1,
       dbo.tblAssetLink.Priority
FROM   dbo.tblBlog
       LEFT OUTER JOIN dbo.tblAssetLink
         ON dbo.tblBlog.BID = dbo.tblAssetLink.BID
       LEFT OUTER JOIN dbo.tblAssets
         ON dbo.tblAssetLink.AID = dbo.tblAssets.AID
WHERE  ( dbo.tblBlog.Deleted = 'False' )

ORDER  BY dbo.tblAssetLink.Priority, tblBlog.DateAdded DESC 

修改

更改了Whereorder by ....

预期产出:

tblBlog.BID = 123

tblBlog.DateAdded = 12/04/2015

tblBlog.Header = This is a header

tblBlog.AddedBy = Persons name

tblBlog.PContent = *text*

tblBlog.Category = Category name

tblBlog.Deleted = False

tblBlog.Intro = *text*

tblBlog.Tags = Tag, Tag, Tag

tblAssets.Name = some.jpg

tblAssets.Description = Asset desc

tblAssets.Location = Location name

tblAssets.Priority = True

3 个答案:

答案 0 :(得分:0)

除非它们都具有相同的属性,否则无法连接三个表。如果所有表都有BID,但第二个连接尝试加入AID,它将起作用。哪个不行。他们都必须有BID。

答案 1 :(得分:0)

根据您的评论

  

我想获得的每个博客帖子只有一个资产(排名第一   按优先顺序)

您可以按以下方式更改查询。我建议将dbo.tblAssetLink的连接更改为已过滤的连接,其中每个博客只包含一个(最高优先级)链接。

SELECT dbo.tblBlog.BID,
       dbo.tblBlog.DateAdded,
       dbo.tblBlog.PMonthName,
       dbo.tblBlog.PDay,
       dbo.tblBlog.Header,
       dbo.tblBlog.AddedBy,
       dbo.tblBlog.PContent,
       dbo.tblBlog.Category,
       dbo.tblBlog.Deleted,
       dbo.tblBlog.Intro,
       dbo.tblBlog.Tags,
       dbo.tblAssets.Name,
       dbo.tblAssets.Description,
       dbo.tblAssets.Location,
       dbo.tblAssets.Deleted AS Expr1,
       dbo.tblAssetLink.Priority
FROM   dbo.tblBlog
       LEFT OUTER JOIN 
       (SELECT BID, AID, 
        ROW_NUMBER() OVER (PARTITION BY BID ORDER BY [Priority] DESC) as N 
        FROM dbo.tblAssetLink) AS filteredAssetLink
         ON dbo.tblBlog.BID = filteredAssetLink.BID
       LEFT OUTER JOIN dbo.tblAssets
         ON filteredAssetLink.AID = dbo.tblAssets.AID
WHERE dbo.tblBlog.Deleted = 'False' AND filteredAssetLink.N = 1
ORDER  BY tblBlog.DateAdded DESC

答案 2 :(得分:0)

使用OUTER APPLY

DECLARE @b TABLE ( BID INT )
DECLARE @a TABLE ( AID INT )
DECLARE @ba TABLE
    (
      BID INT ,
      AID INT ,
      Priority INT
    )

INSERT  INTO @b
VALUES  ( 1 ),
        ( 2 )

INSERT  INTO @a
VALUES  ( 1 ),
        ( 2 ),
        ( 3 ),
        ( 4 )

INSERT  INTO @ba
VALUES  ( 1, 1, 1 ),
        ( 1, 2, 2 ),
        ( 2, 1, 1 ),
        ( 2, 2, 2 )


SELECT  *
FROM    @b b
        OUTER APPLY ( SELECT TOP 1
                                a.*
                      FROM      @ba ba
                                JOIN @a a ON a.AID = ba.AID
                      WHERE     ba.BID = b.BID
                      ORDER BY  Priority
                    ) o

输出:

BID AID
1   1
2   1

类似的东西:

SELECT  b.BID ,
        b.DateAdded ,
        b.PMonthName ,
        b.PDay ,
        b.Header ,
        b.AddedBy ,
        b.PContent ,
        b.Category ,
        b.Deleted ,
        b.Intro ,
        b.Tags ,
        o.Name ,
        o.Description ,
        o.Location ,
        o.Deleted AS Expr1 ,
        o.Priority
FROM    dbo.tblBlog b
        OUTER APPLY ( SELECT    TOP 1 
                                a.* ,
                                al.Priority
                      FROM      dbo.tblAssetLink al
                                JOIN dbo.tblAssets a ON al.AID = a.AID
                      WHERE     b.BID = al.BID
                      ORDER BY al.Priority
                    ) o
WHERE   b.Deleted = 'False'