sql - 如果数据保持不变,有没有办法为同一个 SQL 查询获得不同的结果?

标签 sql tsql sql-server-2008

当我运行这个查询时,我间歇性地得到一个不同的结果集......有时它会给出 1363,有时是 1365,有时是 1366 结果。数据没有变化。什么可能导致这种情况,有没有办法防止它?查询看起来像这样:

SELECT * 
FROM 
    (
            SELECT  
                        RC.UserGroupId,
                        RC.UserGroup,
                        RC.ClientId AS CLID,                     
                        CASE WHEN T1.MultipleClients = 1 THEN RC.Salutation1 ELSE RC.DisplayName1 END AS szDisplayName,
                        T1.MultipleClients,
                        RC.IsPrimaryRecord,
                        RC.RecordTypeId,
                        RC.ClientTypeId,
                        RC.ClientType,
                        RC.IsDeleted,
                        RC.IsCompany,                                            
                        RC.KnownAs,
                        RC.Salutation1,
                        RC.FirstName, 
                        RC.Surname,                   
                        Relationship, 
                        C.DisplayName Client,
                        RC.DisplayName RelatedClient, 
                        E.Email,                                                            
                        RC.DisplayName  + ' is the ' + R.Relationship + ' of ' + C.DisplayName Description,
                        ROW_NUMBER() OVER (PARTITION BY E.Email ORDER BY Relationship DESC) AS sequence_id


            FROM 
                        SSDS.Client.ClientExtended C 
                                                                              INNER JOIN 
                        SSDS.Client.ClientRelationship R WITH (NOLOCK)ON C.ClientId = R.ClientID 
                                                                              INNER JOIN 
                        SSDS.Client.ClientExtended RC WITH (NOLOCK)ON R.RelatedClientId = RC.ClientId
                                                                              LEFT OUTER JOIN
                        SSDS.Client.Email E WITH (NOLOCK)ON RC.ClientId = E.ClientId                 
                                                                              LEFT OUTER JOIN 
                        SSDS.Client.UserDefinedData UD WITH (NOLOCK)ON C.ClientId = UD.ClientId AND C.UserGroupId = UD.UserGroupId 
                                                                              INNER JOIN                                                                 

                        (
                              SELECT 
                                          E.Email, 
                                          CASE WHEN (COUNT(DISTINCT RC.DisplayName) > 1) THEN 1 ELSE 0 END AS MultipleClients 

                              FROM
                                          SSDS.Client.ClientExtended C 
                                                                                                INNER JOIN 
                                          SSDS.Client.ClientRelationship R WITH (NOLOCK)ON C.ClientId = R.ClientID 
                                                                                                INNER JOIN 
                                          SSDS.Client.ClientExtended RC WITH (NOLOCK)ON R.RelatedClientId = RC.ClientId
                                                                                                LEFT OUTER JOIN
                                          SSDS.Client.Email E WITH (NOLOCK)ON RC.ClientId = E.ClientId                 
                                                                                                LEFT OUTER JOIN 
                                          SSDS.Client.UserDefinedData UD WITH (NOLOCK)ON C.ClientId = UD.ClientId AND C.UserGroupId = UD.UserGroupId

                              WHERE 
                                          Relationship IN ('z-Group Principle', 'z-Group Member ')           
                                          AND E.Email IS NOT NULL

                              GROUP BY E.Email 

                        ) T1 ON E.Email = T1.Email


            WHERE 

                                                Relationship IN ('z-Group Principle', 'z-Group Member ')           
                                                AND E.Email IS NOT NULL                                         
    ) T


WHERE       
            sequence_id = 1
            AND T.UserGroupId IN (Select * from iCentral.dbo.GetSubUserGroups('471b9cbd-2312-4a8a-bb20-35ea53d30340',0))         
            AND T.IsDeleted = 0           
            AND T.RecordTypeId = 1 
            AND T.ClientTypeId IN
            (
                        '1',              --Client
                        '-1652203805'    --NTU                      
            )        

        AND T.CLID NOT IN
          (
            SELECT DISTINCT  
                               UDDF.CLID
            FROM
                   SLacsis_SLM.dbo.T_UserDef UD WITH (NOLOCK) 
                          INNER JOIN
                   SLacsis_SLM.dbo.T_UserDefData UDDF WITH (NOLOCK)
                   ON UD.UserDef_ID = UDDF.UserDef_ID
                          INNER JOIN
                   SLacsis_SLM.dbo.T_Client CLL WITH (NOLOCK)
                   ON CLL.CLID = UDDF.CLID AND CLL.UserGroup_CLID = UD.UserID

            WHERE 
                           UD.UserDef_ID in    
                                    (
                                    'F68F31CE-525B-4455-9D50-6DA77C66FEE5',                                    
                                    'A7CECB03-866C-4F1F-9E1A-CEB09474FE47'  
                                    )

                           AND UDDF.Data = 'NO'
           ) 


ORDER BY T.Surname

编辑:

我已经删除了所有 NOLOCK(包括 View 和 UDF 中的那些),但我仍然遇到同样的问题。对于嵌套选择(T),我每次都得到相同的结果,如果我在查询开始时将 T 的结果集放入临时表并连接到临时表而不是嵌套选择,那么最终结果集是每次运行查询时都一样。

编辑2:

我一直在对 ROW_NUMBER() 进行更多阅读……我正在按电子邮件进行分区(其中有重复)并按关系排序(其中只有 2 个关系中的 1 个)。这是否会导致查询不确定,有没有办法解决这个问题?

EDIT3:

如果有人感兴趣,这里是实际的执行计划 http://www.mediafire.com/?qo5gkh5dftxf0ml .是否可以看到它正在以从执行计划中提交的读取方式运行?我已经使用 WinMerge 比较了文件,唯一的区别似乎是计数 (ActualRows="")。

编辑4:

这有效:
SELECT * FROM 
(
   SELECT *, 
             ROW_NUMBER() OVER (PARTITION BY B.Email ORDER BY Relationship DESC) AS sequence_id
             FROM
            (

                                    SELECT DISTINCT  
                                    RC.UserGroupId,
                                    ...
            ) B...

编辑5:

当连续两次运行相同的 ROW_NUMBER() 查询(原始问题中的 T,只需选择 RC.DisplayName 和 ROW_NUMBER)时,我会为某些人获得不同的排名:

enter image description here

有没有人对为什么或如何在包含重复项的结果集上的 ROW_NUMBER() 每次运行时排名不同并最终改变结果数量有很好的解释/示例?

编辑6:

好的,我认为这对我来说很有意义。当两个人拥有相同的电子邮件地址(例如一对夫妻)和关系时,就会发生这种情况。我猜在这种情况下,他们的 ROW_NUMBER() 排名是任意的,并且每次运行时都可以改变。

最佳答案

您全面使用 NOLOCK 意味着您正在执行脏读,并且会看到未提交的数据、将回滚的数据、 transient 和不一致的数据等

脱掉这些,再试一次,报告请求

编辑:删除了 NOLOCKS 的一些选项

  • 数据真的在变
  • 某些参数或过滤器正在更改(例如 GETDATE)
  • 每次在不同内核上运行的一些浮点比较
    在 dba.se 上看到这个 https://dba.stackexchange.com/q/4810/630
  • 在 udfs 或 View 中嵌入 NOLOCK(例如 iCentral.dbo.GetSubUserGroups)
  • ...
  • 关于sql - 如果数据保持不变,有没有办法为同一个 SQL 查询获得不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7123036/

    相关文章:

    sql - 从日期时间获取时间间隔

    sql - 选择子字符串 SQL

    MySQL 使用 UNION 连接 3 个表

    sql - 在 MS Access 中通过 SQL 指定日期/时间字段格式

    tsql - 查询大表

    mysql - 如何在 sql 中创建循环,这是这里最好的技术吗?

    sql - 由于内存压力,AppDomain 被标记为卸载

    sql - 选择数据到 Postgres 数组中

    sql-server - 更改列: null to not null

    sql-server - 当时间戳(rowversion)溢出时会发生什么?