0

環境: MS SQL Server 2008。

次の 2 つのクエリがあります。1 つは 891 行を返しますが、これは間違っています。もう 1 つは正しい結果サイズである 49 行を返します。どちらのクエリも 2 つのサブクエリを使用し、サブクエリの順序が反転することを除いて、基本的に同じです。

次のようにコメントされEntitlementsたサブクエリは、ログインしているユーザーが他のサブクエリを表示する資格がある行を返し、ユーザーの検索基準によってさらに制限します。

結果セットのサイズが異なる理由を誰か説明してもらえますか?

Entitlementa を使用したサブクエリと、フェッチプロセスの最後で結果をフィルタリングするように機能する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

私は問題を見つけ、同じ状況で他の人を助けるためにリストしました:

のようでしR2MS SQLServer2008 R2

1台のサーバーはインストールされていSQLServer 2008ない単純な古いもので、もう1台は.R2R2

これらのクエリを で実行すると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 に答える