有没有办法让这个SQL更小?
CASE
WHEN @contentType = 'PrimaryBannerItem' THEN
[dbo].[DeathStar_GetContentLink] (@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, ''))
ELSE
[dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, ''))
END AS [Image],
CASE
WHEN @contentType = 'PrimaryBannerItem' THEN
dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId)
ELSE
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, ''))
END AS Link,
让它看起来更像
CASE
WHEN @contentType = 'PrimaryBannerItem' THEN
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image]
dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
ELSE
[dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image]
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
END
因为正如您所看到的,它使代码更具可读性,它减少了使用的行数并避免了冗余。
答案 0 :(得分:1)
如果在两种情况下返回的结果集相同,也许你可以玩一个小技巧:
-- This query will return data only when @contentId = 'PrimaryBannerItem'
SELECT
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image]
,dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
,OtherFields
FROM
YourTables
WHERE
(@contentId = 'PrimaryBannerItem')
-- Other WHERE clauses here
UNION ALL
-- This query will return data only when @contentId <> 'PrimaryBannerItem'
SELECT
[dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image]
,[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
,OtherFields
FROM
YourTables
WHERE
(@contentId <> 'PrimaryBannerItem')
-- Other WHERE clauses
这样,您不需要使用任何IF,CASE等。
注意:如果您开始有更复杂的条件,例如依赖于其他参数组合的值,这可能不是最有效的方法,无论是在性能方面,还是更重要的是,维护
答案 1 :(得分:0)
不确定这是否会更好,但是如果不必重复整个查询或对每个列使用重复的CASE ... WHEN ... ELSE ...
表达式,可能没有其他选项,例如:
SELECT
…
COALESCE(choice1.Image, choice2.Image) AS Image,
COALESCE(choice1.Link , choice2.Link ) AS Link,
…
FROM
…
OUTER APPLY (
SELECT
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image],
dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
WHERE @contentType = 'PrimaryBannerItem'
) AS choice1
OUTER APPLY (
SELECT
[dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image],
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
WHERE @contentType <> 'PrimaryBannerItem'
/* or, perhaps, "WHERE @contentType = 'something else'" */
) AS choice2
WHERE
…
在两个OUTER APPLY之间,只有一个可以返回一行,另一个将始终返回一个空行集,并且其列将相应地计算为NULL。这意味着你可以使用COALESCE返回“正确”的结果:只需按照必要的顺序指定相应的列,然后返回第一个非NULL的列。
答案 2 :(得分:0)
这个解决方案可行吗?
-- First case
IF @contentType = 'PrimaryBannerItem' BEGIN
SELECT [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image],
dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
-- Second case
END ELSE BEGIN
SELECT [dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image],
[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
END
如果这些是你选择的唯一领域,它肯定会看起来更干净。但是我很确定我没有看到你的整个代码,所以这可能无法满足你的需求。
答案 3 :(得分:0)
没有。 CASE表达式返回标量,单个值。它不能返回两个值;它不能返回两列的值。