首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQL查询可以在分页后连接吗?

SQL查询可以在分页后连接吗?
EN

Stack Overflow用户
提问于 2020-02-27 01:05:50
回答 3查看 52关注 0票数 0

我有一个类似下面这样的简单查询,我用它来检索一个企业及其所有联系人。

代码语言:javascript
复制
SELECT  *
FROM Business as business
    JOIN Contact as contact
        ON contact.BusinessEntityId = business.Id
WHERE business.Id = '12345'

现在我想做一些类似以下的事情:

代码语言:javascript
复制
SELECT  *
FROM Business as business
    JOIN Contact as contact
        ON contact.BusinessEntityId = business.Id
WHERE business.State = 'TX'
ORDER BY business.Id
OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY

问题是,分页发生在整个查询返回的行上,这意味着我可能会获得页面上最后一个企业的联系人的部分结果。我想要的是对来自WHERE的结果进行分页,然后将这些结果与联系人连接起来。这样,我就可以在页面上显示每个企业的所有联系信息。

有没有办法做到这一点,而不是执行单独的查询来获取每个企业的联系人?

EN

回答 3

Stack Overflow用户

发布于 2020-02-27 05:13:22

我认为临时表是最简单的方法。

代码语言:javascript
复制
SELECT  *
INTO #temp
FROM Business as business
WHERE business.State = 'TX'
ORDER BY business.Id
OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY


SELECT *
FROM #temp as business
JOIN Contact as contact
   ON contact.BusinessEntityId = business.Id

这也应该使它运行得相当快,因为连接只会发生在20个记录上。这也是假设您每个业务只有一个联系人,否则您将在第二个连接上获得超过20个记录,并且您将不得不在那里运行偏移/获取。

票数 1
EN

Stack Overflow用户

发布于 2020-02-27 05:20:01

这可以通过WITH TIES子句来完成,但是SQL Server不支持它:

代码语言:javascript
复制
OFFSET 0 ROWS FETCH NEXT 20 ROWS WITH TIES;

但是您可以使用DENSE_RANK自己进行分页

代码语言:javascript
复制
SELECT *
FROM
(
  SELECT b.*, c.*, DENSE_RANK() OVER (ORDER BY b.id) AS rn
  FROM business b
  JOIN contact c ON c.businessentityid = b.id
  WHERE b.state = 'TX'
) ranked
WHERE rn BETWEEN 101 AND 120;

这将跳过前100个ID,并为您提供接下来的20个ID,而不管每个ID有多少行。

票数 0
EN

Stack Overflow用户

发布于 2020-02-27 12:05:53

Alex的回答几乎完全符合我的要求。谢谢Alex,这给了我最终解决方案所需的东西。我已经将你的帖子标记为解决方案,但我认为将来阅读这篇文章的任何人都会想要使用最终的解决方案,因为它返回了我需要的确切结果,它更简单,而且性能更好。所以,这就是它。

注:当我写这篇文章的时候,我还没有看到Thorsten的帖子。

为了使用临时表获得正确的结果,我必须使用LEFT JOIN,因为有些企业没有联系人。仅使用JOIN会导致丢失业务记录。另外,可能应该去掉末尾的表。这是上述查询的工作版本。

代码语言:javascript
复制
SELECT * INTO #temp
FROM Business AS business
WHERE business.State = 'TX'
ORDER BY business.Id
OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY

SELECT *
FROM #temp AS business
LEFT JOIN Contact AS contact ON contact.Id = business.Id

DROP TABLE #temp

这是可行的,但性能相当差。经过一些研究后,我意识到这可以通过嵌套查询来完成。这是我要使用的修改后的查询。

代码语言:javascript
复制
SELECT *
FROM
  (SELECT *
   FROM Business AS business
   WHERE business.State = 'TX'
   ORDER BY business.Id
   OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY) AS business
LEFT JOIN Contact AS contact ON contact.Id = business.Id
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60419017

复制
相关文章

相似问题

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