0

环境:MS SQL Server 2008。

我有以下两个查询,一个返回 891 行,这是错误的,另一个是 49,正确的结果大小。这两个查询都使用了两个子查询,它们本质上是相同的,只是子查询的顺序被翻转了。

注释为的子查询Entitlements返回登录用户有权查看其他子查询的行,这些子查询进一步受到用户搜索条件的限制。

谁能解释为什么结果集大小不同?

我认为这与Entitlement使用 a 的子查询left outer join以及where clause在获取过程的最后过滤结果有关。但不确定。

查询 1(错误的结果集):

    select
    this_.PROFILE_ID as y0_,
    personalda1_.lastName as y1_,
    personalda1_.fullName as y2_ 
from
    PROFILE this_ 
inner join
    PERSONALDATA personalda1_ 
        on this_.PERSONALDATA_ID=personalda1_.PERSONALDATA_ID 
where
    this_.PROFILE_ID in (
        /* Entitlements */ select
            this_.PROFILE_ID as y0_ 
        from
            PROFILE this_ 
        left outer join
            APPOINTMENTDETAILS appointmen1_ 
                on this_.PROFILE_ID=appointmen1_.PROFILE_ID 
        left outer join
            OTHERAPPOINTMENT othera2_ 
                on this_.PROFILE_ID=othera2_.PROFILE_ID 
        where
            (
                appointmen1_.orgUnit='00000177'
                or othera2_.organizationUnit='00000177'
            )
    ) 
    and this_.PROFILE_ID in (
        /* criteria query */ select
            distinct this_.PROFILE_ID as y0_ 
        from
            PROFILE this_ 
        inner join
            APPOINTMENTDETAILS appointmen1_ 
                on this_.PROFILE_ID=appointmen1_.PROFILE_ID 
        where
            appointmen1_.endDate='9999-12-31'
            and appointmen1_.area='ABCD'
    ) 
order by
    personalda1_.lastName asc;

查询 2(正确的结果集):

    select
    this_.PROFILE_ID as y0_,
    personalda1_.lastName as y1_,
    personalda1_.fullName as y2_ 
from
    PROFILE this_ 
inner join
    PERSONALDATA personalda1_ 
        on this_.PERSONALDATA_ID=personalda1_.PERSONALDATA_ID 
where
    this_.PROFILE_ID in (
        select
            distinct this_.PROFILE_ID as y0_ 
        from
            PROFILE this_ 
        inner join
            APPOINTMENTDETAILS appointmen1_ 
                on this_.PROFILE_ID=appointmen1_.PROFILE_ID 
        where
            appointmen1_.endDate='9999-12-31'
            and appointmen1_.area='ABCD'
    ) 
    and this_.PROFILE_ID in (
    /* Entitlements */ select
            this_.PROFILE_ID as y0_ 
        from
            PROFILE this_ 
        left outer join
            APPOINTMENTDETAILS appointmen1_ 
                on this_.PROFILE_ID=appointmen1_.PROFILE_ID 
        left outer join
            OTHERAPPOINTMENT other2_ 
                on this_.PROFILE_ID=other2_.PROFILE_ID 
        where
            (
                appointmen1_.orgUnit='00000177'
                or other2_.organizationUnit='00000177'
            )            
    ) 
order by
    personalda1_.lastName asc;

试图理解查询执行计划,但并不容易理解。任何帮助将不胜感激。

4

2 回答 2

0

我发现了问题,列出以帮助处于相同情况的其他人:

它是R2,如在MS SQLServer2008 R2

结果发现一台服务器很旧SQLServer 2008,没有R2安装,另一台是R2.

当这些查询在 上运行时R2,两者都产生了相同的结果。

于 2013-02-05T14:45:29.317 回答
0

转到“不良”结果并找到不应返回的记录。试着弄清楚为什么它会被包含在内,你可能会发现问题所在。

此外,您不需要distinct在子查询中。

另外:这与正确的查询相同吗?

SELECT
    this_.PROFILE_ID as y0_,
    personalda1_.lastName as y1_,
    personalda1_.fullName as y2_ 
from
    PROFILE this_ 
inner join
    PERSONALDATA personalda1_ 
        on this_.PERSONALDATA_ID=personalda1_.PERSONALDATA_ID 
where
    this_.PROFILE_ID in (
        /* Entitlements */ 
        select
            this_.PROFILE_ID as y0_ 
        from
            PROFILE this_ 
        left outer join
            APPOINTMENTDETAILS appointmen1_ 
                on this_.PROFILE_ID=appointmen1_.PROFILE_ID 
        left outer join
            OTHERAPPOINTMENT othera2_ 
                on this_.PROFILE_ID=othera2_.PROFILE_ID 
        where
            (
                appointmen1_.orgUnit='00000177'
                or othera2_.organizationUnit='00000177'
            )
        AND
            appointmen1_.endDate='9999-12-31'
        AND
            appointmen1_.area='ABCD'
    ) 
于 2013-01-28T13:07:02.887 回答