【问题标题】:Get top n records from each of 5 tables从 5 个表中的每一个中获取前 n 条记录
【发布时间】:2022-01-03 17:33:04
【问题描述】:

在 SQL Server 2016 中,我有 5 个大表。在一个查询中从 5 个表中的每一个表中选择前 1000 条记录的最佳方法是什么?

这例如返回太多数据。

Select * 
from table1 
cross apply table2
cross apply table3 
cross apply table4 
cross apply table5 with(nolock)

此外,我希望从 5 个表中的每一个中获取每一列..但只是每个表中的前 1000 行。

【问题讨论】:

  • 旁白:为什么你有with(nolock) 你认为它对你的查询有什么影响?
  • 默认事务隔离级别是 READ COMMITTED 隔离级别,在该隔离级别中检索更改的数据将被阻止,直到这些更改被提交。 WITH (NOLOCK) 表提示用于覆盖特定查询中表或视图内表的默认事务隔离级别,允许用户在不受锁影响的情况下检索数据
  • 我想你也知道它可能返回完全错误的结果,包括但不限于:读取行甚至整页两次或根本不读取,读取数据唯一或外键约束失败,甚至检查约束,本应是唯一的行导致连接加倍,可能导致“数据已移动”错误,等等。对于几乎所有涉及锁的问题,这都是错误的解决方案:如果您有并发写入者,请使用SNAPSHOT。如果没有并发作者,那么您还担心什么?最多你可以为性能做TABLOCK
  • 如果我们假设每个表有 10 列,您希望结果集包含 5000 行包含 10 列还是 1000 行包含 50 列之一?

标签: sql sql-server


【解决方案1】:

使用UNION ALL 而不是CROSS APPLY

注意:如果您只有一个查询,那么您只有一个结果集。结果集必须具有明确定义的列列表。因此,您必须告诉 SQL Server 这些不同表中的哪些列是“相等的”,方法是将它们放在相同的位置。

例子:

SELECT TOP 1000 a, b, c FROM table1 ORDER BY d
UNION ALL
SELECT TOP 1000 x, y, z FROM table2 ORDER BY w
UNION ALL
...

此时ax的数据类型必须兼容,by等数据类型相同。

第一个 SELECT 语句中的列名(本例中为abc)将用作结果集的列名。

【讨论】:

  • 嗯。我试过联合所有但得到这个消息。使用 UNION、INTERSECT 或 EXCEPT 运算符组合的所有查询必须在其目标列表中具有相同数量的表达式。所有 5 个表中的列并不相同,并且不一定是相似的数据类型。
  • @tonys777:如果它们有不同类型的列,你想如何将它们组合成一个结果集?
【解决方案2】:

如果您不关心它们是相同的结果集,只需一个查询返回所有这些,您可以在 1 个查询中创建 5 个单独的选择语句:

SELECT TOP 1000 * FROM table1
SELECT TOP 1000 * FROM table2
SELECT TOP 1000 * FROM table3
SELECT TOP 1000 * FROM table4
SELECT TOP 1000 * FROM table5

如果由于某种原因您需要将它们放在一个结果集中,包括行号列,那么将它们加入行号可能会起作用:

SELECT *
FROM (SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY [orderCol]) AS RN, * FROM table1) AS T1
JOIN (SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY [orderCol]) AS RN, * FROM table2) AS T2 ON T1.RN = T2.RN
JOIN (SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY [orderCol]) AS RN, * FROM table3) AS T3 ON T1.RN = T3.RN
JOIN (SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY [orderCol]) AS RN, * FROM table4) AS T4 ON T1.RN = T4.RN
JOIN (SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY [orderCol]) AS RN, * FROM table5) AS T5 ON T1.RN = T5.RN

【讨论】:

    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 2021-08-31
    • 2016-11-26
    • 1970-01-01
    相关资源
    最近更新 更多