0

我正在尝试从两个表中获取产品和图像列表。当我加入他们并在产品表中的 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

问题出在“真”的情况下。这就是引发错误的原因。

产品表

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 只返回一个。

我想要的返回数据应该是这样的:

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

我尝试了各种合并(NULLIF、左连接和不同的语句)的组合,但我还没有让所有三种产品都按需要显示。

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 仅用于标记图像的存在而不是作为业务规则(显示/不显示此特定产品的图像),您可以删除 case 以支持 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 回答