如何在SQL Server中从TOP中排除LEFT JOINed表?

时间:2012-04-16 08:09:52

标签: sql-server sql-server-2000

假设我有两本书和两张相应版本的表格。

我的查询如下:

SELECT TOP 10 * FROM
(SELECT hbID, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate
 FROM hardback
 LEFT JOIN hardbackEdition on hbID = hbedID
 UNION 
 SELECT pbID, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate
 FROM paperback
 Left JOIN paperbackEdition on pbID = pbedID
) books
WHERE hbPublisherID = 7
ORDER BY hbPublishDate DESC

如果前两本精装书和/或平装书有5个版本,则此查询仅返回两本书。但是,我希望TOP 10仅适用于返回的实际图书记录数。有没有办法可以选择10本实际书籍,还能获得所有相关的版本记录?

如果它是相关的,我没有CREATE和DROP临时表的数据库权限。

感谢阅读!

更新

澄清:平装表有一个平装版的相关表格。精装表有一个相关的精装版表。精装本和平装书彼此无关,除非用户(希望!)看到它们一起显示。

3 个答案:

答案 0 :(得分:1)

如果我理解正确,你可以通过

获得所有相关版本的10本书
  • 使用WITH语句返回初始的完整结果集
  • 使用GROUP BY
  • 选择10本不同的书籍
  • JOIN该小组的结果是保留给定10本书的所有信息。

SQL声明

;WITH books AS (
  SELECT  hbID, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate
  FROM    hardback
          LEFT JOIN hardbackEdition on hbID = hbedID
  WHERE   hbPublisherID = 7          
  UNION ALL
  SELECT  pbID, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate
  FROM    paperback
          LEFT JOIN paperbackEdition on pbID = pbedID
  WHERE   hbPublisherID = 7
)
SELECT  *
FROM    books b
        INNER JOIN (
          SELECT TOP 10 hbID
          FROM   books
          GROUP BY
                hbID
        ) bt ON bt.hbID = b.hbID

或者如果您只想写一次where子句

;WITH books AS (
  SELECT  hbID, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate
  FROM    hardback
          LEFT JOIN hardbackEdition on hbID = hbedID
  UNION ALL
  SELECT  pbID, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate
  FROM    paperback
          LEFT JOIN paperbackEdition on pbID = pbedID
)
, q AS (
  SELECT  *
  FROM    books
  WHERE   hbPublisherID = 7          
)
SELECT  *
FROM    q b
        INNER JOIN (
          SELECT TOP 10 hbID
          FROM   q
          GROUP BY
                hbID
        ) bt ON bt.hbID = b.hbID

答案 1 :(得分:0)

不那么容易。您需要将Top 10仅应用于精装版和平装表,而不使用连接。然后将结果加入数据。

以下查询仅在hbID和pbID始终唯一时才有效。如果没有,它会变得更复杂。您需要将它们分开或在查询中添加另一列以区分它们。

SELECT *
FROM
  (SELECT hbID as id, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate
   FROM hardback
   LEFT JOIN hardbackEdition on hbID = hbedID
   UNION 
   SELECT pbID as id, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate
   FROM paperback
   Left JOIN paperbackEdition on pbID = pbedID
  ) books
INNER JOIN 
  (SELECT TOP 10 * 
  FROM
    (SELECT hbID as id, hbPublisherID as publishedId, hbPublishDate as publishDate
     FROM hardback
     UNION 
     SELECT pbID as id, pbPublisherID as publishedId, pbPublishDate as publishDate
     FROM paperback
    ) 
  WHERE publisherID = 7
  ORDER BY publishDate DESC
  ) topTen 
  on books.id = TopTen.id

答案 2 :(得分:0)

这应该使用发布商7的精装版抓住最近出版的十本书:

select  *
from    (
        select  top 10 title
        from    hardback
        where   hbPublisherID = 7
        group by
                title
        order by
                hbPublishDate desc
        ) top_titles
left join
      hardback
on    hardback.hbTitle = top_titles.title
left join
      paperback
on    paperback.pbTitle = top_titles.title