SQL Server +选择包含子表项的记录

时间:2013-04-26 04:39:40

标签: sql sql-server

我有一张有一张照片子表的帖子表,所以一张帖子可以有很多照片,其中一张照片表栏是[优先]。

我需要从帖子表中选择记录,只有在另一个表中具有最高优先级的照片:

所以结果应该是:

Photo  Post
pic1   Article1
picX   Article2

目前我的结果显示为

Photo  Post
pic1   Article1
pic2   Article1
picX   Article2

使用此查询:

 SELECT  [Photo], 
         [PostTitle]
 FROM [Post] sp
 INNER JOIN [PostPhotos] spp
 ON (sp.AutoId = spp.PostId)
 WHERE sp.[AutoId] IN (SELECT [PostID] 
                       FROM [Favorites] 
                       WHERE [UserId] = 'UserXXX')

我尝试了一个连接查询但没有成功:

 SELECT photo, 
        [PostTitle],
        [AskingPrice]
 FROM (SELECT sp.[AutoId], 
              [PostTitle] 
       FROM [SellPost] sp
       WHERE sp.[AutoId] IN (SELECT [PostID] 
                             FROM [Favorites] 
                             WHERE [UserId] = 'UserId') )a
 full OUTER JOIN(SELECT TOP 1 [PostId], 
                        [photo] 
                 FROM [PostPhotos] spp 
                 WHERE PostId IN (SELECT [PostID] 
                                  FROM [Favorites] 
                                  WHERE [UserId] = 'UserXXX') 
                 ORDER BY [Priority] ASC )b
  on (a.AutoId = b.PostId)
  order by a.AutoId; 

我的表格:

Table Post
PostId, PostTitle

Table PostPhotos
AutoId, PostId, Photo, Priority --> 1 post can have many photos

有人可以请帮助。感谢。

5 个答案:

答案 0 :(得分:0)

尝试使用此提示:

SELECT [p].[PostId],[PostTitle],[Photo] FROM [Post] p
INNER JOIN [PostPhots] pp
ON [p].[PostId] = [pp].[PostId] 
WHERE [p].[PostId] 
IN (SELECT TOP 1 [PostId] FROM [PostPhotos] ORDER BY [Priority] DESC)

答案 1 :(得分:0)

您的描述中有一些不清楚的内容(例如AutoId是什么,PostPhotos的主要关键是什么?您使用Favorites做了什么/该表看起来像什么)。但这是一般性的想法:

WITH RankedPhotos AS (
  SELECT
    PostId,
    AutoId, -- I'm assuming this is the primary key of PostPhotos?
    RANK() OVER (PARTITION BY AutoId, PostId ORDER BY Priority ASC) AS PhotoRank
  FROM
    Post p JOIN
    PostPhotos pp ON
      p.PostId = pp.PostId
), TopPhotos AS (
  SELECT
    PostId,
    AutoId
  FROM
    RankedPhotos
  WHERE
    PhotoRank = 1
)
SELECT
  PostTitle,
  Photo
FROM
  RankedPhotos r JOIN
  Post p ON
    r.PostId = p.PostId JOIN
  PostPhotos pp ON
    r.AutoId = p.AutoId

当然你可以解开CTE并使用嵌套的子查询(你也可能完全摆脱TopPhotos),但这可能更容易看到/理解。

基本理念是:

  • RankedPhotos中,“排名”所有Post / PostPhoto
  • TopPhotos中将ID过滤到排名最高的ID
  • 加入原始表格以获取您真正想要的记录

显然,如果您需要按照需要添加的其他条件(如用户)进行过滤。最好尽可能早地在过程中添加(即RankedPhotos),否则数据库最终可能会完成比需要更多的工作。

答案 2 :(得分:0)

子查询不是我最强烈的观点,但我认为以下内容可能有效:

SELECT t1.Photo, t2.PostTitle
FROM Post t2
   INNER JOIN PostPhotos t1 ON (t2.PostID = t1.PostID)
WHERE t1.AutoID IN (SELECT TOP 1 d.AutoID, d.PostID
                        FROM PostPhotos As d
                        WHERE d.PostID = t1.PostID 
                        ORDER BY d.Priority, d.AutoID)

请注意在子查询的顺序中添加了d.AutoID,以防两张照片具有相同的优先级。

编辑我学到了很多关于子查询的知识here

答案 3 :(得分:0)

对于我的帖子中的错误感到抱歉,我想我一直在思考太深,我需要的只是:

   SELECT [p].[AutoId], [PostTitle], [Photo] FROM [Post] p
      INNER JOIN [PostPhotos] pp
      ON [p].[AutoId] = [pp].[PostId] 
      WHERE p.[AutoId] IN (SELECT [PostID] FROM [Favorites] WHERE [UserId] = @UserId)
      AND [Priority] = 1

答案 4 :(得分:0)

SELECT  B.Photo,A.[PostTitle]
FROM    [Post]  A   INNER JOIN
        (SELECT AutoId,PostId,Photo,Priority
        FROM    PostPhotos
        WHERE   Priority =1) B ON A.[PostId] = B.[PostId]

我会这样做, 内连接和左连接都可以得到你想要的结果。