3

Microsoft SQL Server 2008 (10.0.1600.22 / Service Pack 2)に対するクエリから予期しない結果が得られます。

バグでしょうか?

問題を再現するために同様のクエリを作成しようとしましたが、成功しませんでした。したがって、クエリ自体には何も問題はないと思いますが、他の何かがこのやや奇妙な動作を引き起こしています。

何が問題を引き起こしているのかについて、いくつかの提案を期待しています。

まず、次の実際の例を見てください。

DROP TABLE #TempType
DROP TABLE #TempData

SELECT * INTO #TempType FROM (
    SELECT 1 AS Id, 10 AS TempDataFK, 'Do' AS Name, 'CODE1' AS Type   UNION
    SELECT 2 AS Id, 10 AS TempDataFK, 'Re' AS Name, 'CODE2' AS Type   UNION
    SELECT 3 AS Id, 20 AS TempDataFK, 'Mi' AS Name, 'CODE2' AS Type   UNION
    SELECT 5 AS Id, 10 AS TempDataFK, 'Fa' AS Name, 'CODE3' AS Type   UNION
    SELECT 6 AS Id, 20 AS TempDataFK, 'So' AS Name, 'CODE4' AS Type
) sub

SELECT * INTO #TempData FROM (
    SELECT 10 AS Id, 150 AS Number   UNION
    SELECT 20 AS Id, 150 AS Number   UNION
    SELECT 30 AS Id, 150 AS Number   UNION
    SELECT 40 AS Id, 180 AS Number
) sub

SELECT C1.Name Name1,
       C2.Name Name2,
       C3.Name Name3,
       C4.Name Name4,
       #TempData.Id,
       #TempData.Number
FROM #TempData
    LEFT JOIN #TempType C1 (NOLOCK)
        ON #TempData.Id = C1.TempDataFK 
        AND C1.Type = 'CODE1'
    LEFT JOIN #TempType C2 (NOLOCK)
        ON #TempData.Id = C2.TempDataFK 
        AND C2.Type = 'CODE2'
    LEFT JOIN #TempType C3 (NOLOCK)
        ON #TempData.Id = C3.TempDataFK 
        AND C3.Type = 'CODE3'
    LEFT JOIN #TempType C4 (NOLOCK)
        ON #TempData.Id = C4.TempDataFK 
        AND C4.Type = 'CODE4'
WHERE 1=1
    AND (#TempData.Number = 150)
    AND (C1.Name='Mi' OR C2.Name='Mi' OR C3.Name='Mi' OR C4.Name='Mi')

ご覧のとおり、テーブルTempTypeTempData4 回 LEFT JOIN しています。毎回別のエイリアスを付けます。次に、特定の数値 (150) でフィルター処理し、名前の少なくとも 1 つが「Mi」であることを確認します。

結果は期待どおりです。

--------------------------------------------
Name1   Name2   Name3   Name4   Id   Number
NULL    Mi      NULL    So      20   150
--------------------------------------------

それにもかかわらず、クライアント データベースに対して同様のクエリを実行すると、次のようになります。

--------------------------------------------
Name1   Name2   Name3   Name4   Id   Number
Do      Re      Fa      NULL    10   150
NULL    Mi      NULL    So      20   150
NULL    NULL    NULL    NULL    30   150
--------------------------------------------

に似た部分(C1.Name='Mi' OR C2.Name='Mi' OR C3.Name='Mi' OR C4.Name='Mi')はフィルタリングに使われていないかのようです。

クエリは異なりますが、構造
は同じです クライアント データベースのテーブルは一時的なものではなく、既にデータが含まれています。テーブルには他にもさまざまなフィールドがありますが、まだ他のテーブルと結合しているだけです。上記と同じ構造です。

新しいデータベースでレプリケートできませんでし
た 影響を受けるテーブルとフィールドのみを使用して新しいデータベースを作成することで、問題をレプリケートしようとしましたが、問題のレプリケートに成功しませんでした。

スキーマ
言及する価値があるのは、クライアント データベースに複数のスキーマが含まれていることです。TempData と TempType に類似した両方のテーブルは、同じスキーマ (dbo ではない) に属しています。また、TempType.Type に似たフィールドは、別のスキーマの別のテーブルへの外部キーですが、それと結合していないため、関連性があるとは思いませんか?

もう 1 つの特徴
C1.Name などを SELECT の一部として次のように入力すると、次のようになります。

SELECT C1.Name Name1,
       C2.Name Name2,
       C3.Name Name3,
       C4.Name Name4,
       #TempData.Id,
       #TempData.Number,
       CASE WHEN (C1.Name = 'Mi' AND C1.Name IS NOT NULL) THEN 1 ELSE 0 END,
       CASE WHEN (C2.Name = 'Mi' AND C2.Name IS NOT NULL) THEN 1 ELSE 0 END,
       CASE WHEN (C3.Name = 'Mi' AND C3.Name IS NOT NULL) THEN 1 ELSE 0 END,
       CASE WHEN (C4.Name = 'Mi' AND C4.Name IS NOT NULL) THEN 1 ELSE 0 END

クライアント データベースに対して期待される結果が得られます (1 行のみ)。

Name1   Name2   Name3   Name4   Id   Number   (No column name)   (No column name)   (No column name)   (No column name)
NULL    Mi      NULL    So      20   150        0                  1                  0                  0


これを引き起こしている可能性のある提案はありますか?

4

1 に答える 1