我正在使用SQL Server 2008 R2。
我不确定我是否发现了一个奇怪的SQL怪癖,或者(更有可能)我的代码中的某些内容导致了这种奇怪的行为,特别是因为谷歌没有发现任何东西。我有一个名为vwResponsible_Office_Address的视图。
SELECT * FROM vwResponsible_Office_Address
..返回403行
此代码:
SELECT TOP 1000 * FROM vwResponsible_Office_Address
..返回409行,因为它包含6个重复项。
但是这个:
SELECT TOP 1000 * FROM vwResponsible_Office_Address
ORDER BY ID
..再次返回403行。
我可以发布视图的代码,如果它是相关的,但SELECT TOP是否有意义以这种方式工作?我理解SELECT TOP可以按任何顺序自由返回记录,但不明白为什么返回的记录数量会有所不同。
视图确实使用交叉应用,这可能会影响结果集的某些方式?
编辑:按要求查看定义
CREATE VIEW [dbo].[vwResponsible_Office_Address]
AS
SELECT fp.Entity_ID [Reg_Office_Entity_ID],
fp.Entity_Name [Reg_Office_Entity_Name],
addr.Address_ID
FROM [dbo].[Entity_Relationship] er
INNER JOIN [dbo].[Entity] fp
ON er.[Related_Entity_ID] = fp.[Entity_ID]
INNER JOIN [dbo].[Entity_Address] ea
ON ea.[Entity_ID] = fp.[Entity_ID]
CROSS APPLY (
SELECT TOP 1 Address_ID
FROM [dbo].[vwEntity_Address] vea
WHERE [vea].[Entity_ID] = fp.Entity_ID
ORDER by ea.[Address_Type_ID] ASC, ea.[Address_ID] DESC
) addr
WHERE [Entity_Relationship_Type_ID] = 25 -- fee payment relationship
UNION
SELECT ets.[Entity_ID],
ets.[Entity_Name],
addr.[Address_ID]
FROM dbo.[vwEntity_Entitlement_Status] ets
INNER JOIN dbo.[Entity_Address] ea
ON ea.[Entity_ID] = ets.[Entity_ID]
CROSS APPLY (
SELECT TOP 1 [Address_ID]
FROM [dbo].[vwEntity_Address] vea
WHERE vea.[Entity_ID] = ets.[Entity_ID]
ORDER by ea.[Address_Type_ID] ASC, ea.[Address_ID] DESC
) addr
WHERE ets.[Entitlement_Type_ID] = 40 -- registered office
AND ets.[Entitlement_Status_ID] = 11 -- active
答案 0 :(得分:3)
我认为存在一些非确定性,这意味着不同的访问方法可以返回不同的结果。
查看视图定义唯一可能出现的地方vwEntity_Address
有Entity_ID
的重复项。
这会使top 1 Address_ID
在这种情况下返回任意值,这会在删除重复项时影响union
操作的结果。
肯定这看起来非常可疑
SELECT TOP 1 [Address_ID]
FROM [dbo].[vwEntity_Address] vea
WHERE vea.[Entity_ID] = ets.[Entity_ID]
ORDER by ea.[Address_Type_ID] ASC, ea.[Address_ID] DESC
您要按交叉申请中外部查询的值进行排序。这绝对没有任何影响,因为对于特定的CROSS APPLY
调用,这些将是常量。
您可以尝试更改为
SELECT TOP 1 [Address_ID]
FROM [dbo].[vwEntity_Address] vea
WHERE vea.[Entity_ID] = ets.[Entity_ID]
ORDER by vea.[Address_ID] DESC
答案 1 :(得分:2)
我想知道你的观点是否包含一个功能,直到我结束,你说你使用交叉申请。我认为这是你的问题,如果你对细节感兴趣,请看一下各种查询计划。
编辑:扩大答案 即您的函数是非确定性的,可以为每个输入返回多行,也可以为不同的输入返回相同的行。结合起来,这意味着您将获得您所看到的内容:在某些环境下重复行。为您的视图添加一个独特的方法是解决问题的昂贵方法,更好的方法是更改您的函数,以便任何输入只有一行输出,而对于行输出,只有一个输入将产生该行。 / p> 编辑:我没有看到您现在包含您的视图定义。 你的问题绝对是交叉应用,特别是你在交叉应用中通过交叉应用的OUTSIDE中的值进行排序,使得前1有效地随机。