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')
ご覧のとおり、テーブルTempType
をTempData
4 回 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
これを引き起こしている可能性のある提案はありますか?