我有一个类似下面这样的简单查询,我用它来检索一个企业及其所有联系人。
SELECT *
FROM Business as business
JOIN Contact as contact
ON contact.BusinessEntityId = business.Id
WHERE business.Id = '12345'现在我想做一些类似以下的事情:
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的结果进行分页,然后将这些结果与联系人连接起来。这样,我就可以在页面上显示每个企业的所有联系信息。
有没有办法做到这一点,而不是执行单独的查询来获取每个企业的联系人?
发布于 2020-02-27 05:13:22
我认为临时表是最简单的方法。
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个记录,并且您将不得不在那里运行偏移/获取。
发布于 2020-02-27 05:20:01
这可以通过WITH TIES子句来完成,但是SQL Server不支持它:
OFFSET 0 ROWS FETCH NEXT 20 ROWS WITH TIES;但是您可以使用DENSE_RANK自己进行分页
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有多少行。
发布于 2020-02-27 12:05:53
Alex的回答几乎完全符合我的要求。谢谢Alex,这给了我最终解决方案所需的东西。我已经将你的帖子标记为解决方案,但我认为将来阅读这篇文章的任何人都会想要使用最终的解决方案,因为它返回了我需要的确切结果,它更简单,而且性能更好。所以,这就是它。
注:当我写这篇文章的时候,我还没有看到Thorsten的帖子。
为了使用临时表获得正确的结果,我必须使用LEFT JOIN,因为有些企业没有联系人。仅使用JOIN会导致丢失业务记录。另外,可能应该去掉末尾的表。这是上述查询的工作版本。
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这是可行的,但性能相当差。经过一些研究后,我意识到这可以通过嵌套查询来完成。这是我要使用的修改后的查询。
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.Idhttps://stackoverflow.com/questions/60419017
复制相似问题