我正在尝试从两个表中获取产品和图像的列表。当我加入它们并使用产品表中 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,左连接和不同的语句(,但我还没有让所有三个产品都按预期显示。
除了我在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 仅用于标记图像的存在,而不是作为业务规则(显示/不显示此特定产品的图像(,则可以删除大小写以支持简单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
你为什么要去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