T-SQL SELECT TOP返回重复项
我正在使用SQL Server 2008 R2。T-SQL SELECT TOP返回重复项
我不确定我是否发现了一个奇怪的SQL怪癖,或者(更可能)是我的代码中的某些内容导致了这种奇怪的行为,特别是因为Google什么也没有发现。我有一个名为vwResponsible_Office_Address的视图。
SELECT * FROM vwResponsible_Office_Address
..returns 403行
此代码:
SELECT TOP 1000 * FROM vwResponsible_Office_Address
..returns 409行,因为它包括6个重复。
然而这样的:
SELECT TOP 1000 * FROM vwResponsible_Office_Address ORDER BY ID
再次..returns 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
回答:
我会假设存在一些非确定性,这意味着不同的访问方法可能返回不同的结果。
看看视图定义,如果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有效地随机。
以上是 T-SQL SELECT TOP返回重复项 的全部内容, 来源链接: utcz.com/qa/260778.html