包含多行的SQL Case When语句
有没有办法使这个SQL更小包含多行的SQL Case When语句,sql,sql-server-2005,case-when,Sql,Sql Server 2005,Case When,有没有办法使这个SQL更小 CASE WHEN @contentType = 'PrimaryBannerItem' THEN [dbo].[DeathStar_GetContentLink] (@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) ELSE
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
正如您所见,它使代码更具可读性,减少了使用的行数,避免了冗余。可能不是
您在第二个代码块中建议的方式将不起作用。CASE是一条语句,只能用于返回单个列的值。这就是为什么将案例的结果定义为列,但不能在案例语句中定义列。这就解释了
我能想到的唯一可能性是更新存储过程/函数以允许空值,这样就可以去掉所有isNull。为存储过程解释这一点。可能不是
您在第二个代码块中建议的方式将不起作用。CASE是一条语句,只能用于返回单个列的值。这就是为什么将案例的结果定义为列,但不能在案例语句中定义列。这就解释了
我能想到的唯一可能性是更新存储过程/函数以允许空值,这样就可以去掉所有isNull。为存储过程解释这一点。不确定这是否更好,但如果不重复整个查询或使用重复的大小写,可能没有其他选项。。。什么时候其他的每个列的表达式,如示例中所示:
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
…
在两个外部应用程序之间,只有一个可以返回一行,另一个将始终返回一个空行集,其列将相应地计算为NULL。这意味着您可以使用COALESCE返回正确的结果:只需按必要的顺序指定相应的列,就会返回第一个非空的列。不确定这是否更好,但如果不重复整个查询或使用重复的大小写,可能就没有其他选项了。。。什么时候其他的每个列的表达式,如示例中所示:
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
…
在两个外部应用程序之间,只有一个可以返回一行,另一个将始终返回一个空行集,其列将相应地计算为NULL。这意味着您可以使用COALESCE返回正确的结果:只需按必要的顺序指定相应的列,就会返回第一个非空的列。这个解决方案可行吗
-- 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
如果这些是您选择的唯一字段,那么它看起来肯定会更干净。但是,我很确定我没有看到您的全部代码,因此这可能无法完全满足您的需求。这个解决方案可行吗
-- 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
如果这些是您选择的唯一字段,那么它看起来肯定会更干净。但是,我很确定我没有看到您的全部代码,因此这可能无法提供您想要的内容。否。CASE表达式返回一个标量,即单个值。它不能返回两个值;它不能返回两列的值。否。大小写表达式返回一个标量,即单个值。它不能返回两个值;它不能为两列返回值。如果两种情况下返回的结果集相同,也许您可以玩一个小把戏:
-- 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等
注意:如果您开始遇到更复杂的条件,例如依赖于其他参数组合的值,这可能不是最有效的方法,无论是在性能方面,还是更重要的是在维护方面。如果在这两种情况下返回的结果集相同,也许您可以玩一个小把戏:
-- 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等
注意:如果您开始遇到更复杂的条件,例如依赖于其他参数组合的值,这可能不是最有效的方法,无论是在性能方面,还是更重要的是在维护方面。您是否正在寻找一种工具来为您格式化T-SQL?如果是这样的话,我已经使用SQLPrompt好几年了,并且对它相当满意。我认为使用同义词可以做到这一点。您是否正在寻找一种可以为您格式化T-SQL的工具?如果是这样的话,我已经使用SQLPrompt好几年了,并且对它相当满意。我认为使用同义词可以做到这一点:不尝试去除null,只需同时将值返回到2列中,而不必生成2个不同的大小写。不尝试去除null,只需同时将值返回到2列中,而不必生成2个不同的大小写。即使它们是返回的唯一字段,这是行不通的,因为有些参数是列引用或包含列引用的表达式。明白-我想,总的来说,如果条件列数较高,则希望在IF语句中进行两次完全选择;如果非条件列数较高,则希望对所有内容进行两次完全选择。即使它们是返回的唯一字段,这也不起作用,因为某些参数是列引用或
包含列引用的按。明白-我认为,总的来说,如果条件列的数量较多,您可能希望在IF语句中执行两次完整选择,如果非条件列的数量较多,则希望对所有内容执行CASE列。