0

2 つのテーブルから製品と画像のリストを取得しようとしています。それらに参加し、製品テーブルの HasImage 列でケース スイッチを使用すると、次のエラーが発生します。

エラー:

Subquery returned more than 1 value. 
This is not permitted when the subquery follows =, !=, <, <= , >, >= 
or when the subquery is used as an expression.

商品に画像がない場合、デフォルトの画像に差し替えたい。

選択ステートメントは次のとおりです。

SELECT 

P.[ProductId]
,P.[ProductName]

--If HasImage is false show the default.jpg
,Case P.[HasImage]
WHEN 'True' THEN (Select I.[FileName] as ProductImage FROM [ProductImages] I
INNER JOIN [Product] P on P.ProductId = I.ProductId
  WHERE I.Sequence=0)
WHEN 'False' THEN 'default.jpg'
END

FROM [Product] P
LEFT JOIN [ProductImages] I
on P.ProductId = I.ProductId

問題は「True」の場合です。それがエラーをスローするものです。

製品表

ProductId         ProductName       HasImage
1                 Coffee Mug        True
2                 Pen               False
3                 Pencil            False

製品イメージ表

ProductId         Sequence          FileName
1                 0                 Mug_Image1.jpg
1                 1                 Mug_2.jpg
1                 2                 Mug_Img3.jpg

ProductId=1 の画像は複数ありますが、Sequence = 0 を使用して 1 つだけを返します。

必要な返されたデータは次のようになります。

ProductId         ProductName       ProductImage
1                 Coffee Mug        Mug_Image1.jpg
2                 Pen               default.jpg
3                 Pencil            default.jpg

合体 (NULLIF、Left Joins、およびさまざまなステートメント) のさまざまな組み合わせを試しましたが、3 つの製品すべてを希望どおりに表示することはできませんでした。

4

2 に答える 2

1

OPの下の私のコメントに加えて、これは最初に書かれるべきだったと私が信じるクエリです。

SELECT 
    P.[ProductId]
   ,P.[ProductName]
   --If HasImage is false show the default.jpg
   ,Case P.[HasImage]
         WHEN 'True' 
         THEN I.[FileName]
         WHEN 'False' 
         THEN 'default.jpg'
   END
  FROM [Product] P
  LEFT JOIN [ProductImages] I
    ON P.ProductId = I.ProductId
   -- Filter Sequence 0 only
   -- All products will be retrieved
   -- whether they have associated Image with Sequence = 0
   AND I.Sequence = 0

左結合の右側をフィルタリングすると、左結合のプロパティを保持し、関心のある行のみを結合できます。HasImage が、ビジネス ルール (この特定の製品の画像を表示する/表示しない) としてではなく、画像の存在をマークするためだけに機能する場合は、 simple を優先して大文字と小文字を区別することができますisnull(I.FileName, 'default.jpg')

または (Sql Server 2005 以降)、CROSS APPLYを使用して画像を取得することもできます。

SELECT 
    P.[ProductId]
   ,P.[ProductName]
   ,I.[FileName]
  FROM [Product] P
 OUTER APPLY
 (
    SELECT CASE P.[HasImage]
           WHEN 'True' 
           THEN ProductImages.[FileName]
           WHEN 'False' 
           THEN 'default.jpg'
       END FileName
      FROM [ProductImages]
     WHERE P.ProductId = ProductImages.ProductId
       AND I.Sequence = 0
 ) I
于 2012-05-22T21:59:46.563 に答える
0

なぜに行きたいのINNER JOINですか?

HasImageが TRUE のときにテーブルにイメージがあることが確実な場合は、直接結合を使用することをお勧めします。

このクエリを試してください -

SELECT P.[ProductId], 
       P.[ProductName],
       Case P.[HasImage] 
            WHEN 'True' THEN 
            (Select 
                   TOP 1 -- For Oracle 
                   I.[FileName] as ProductImage FROM [ProductImages] I
             WHERE P.ProductId = I.ProductId
             ORDER BY I.Sequence 
             LIMIT 1 -- For MySQL
             )
            WHEN 'False' THEN 'default.jpg'
         END
FROM [Product] P
于 2012-05-22T19:01:08.353 に答える