大家早上好。我的查询有问题。我想在查询中选择一些东西,如果另一个字段是某种情况。以下查询将更好地解释
select
Case isnull(rl.reason,'Not Found')
When 'D' then 'Discontinued'
When 'N' then 'Not Found'
When 'I' then 'Inactive'
When 'C' then 'No Cost'
When '' then 'Not Found'
End as Reason, ***If statement to select pv.descriptor only if reason is in ('D','I','C')***pv.descriptor
from table1 as rl
left join table2 as v on v.field= rl.field
***Here i want an if statment to run if reason is in ('D','I','C')***
left join table3 as pv on
Case rl.scantype
when 'S' then cast(ltrim(rtrim(pv.field#1)) as varchar)
when 'U' then cast(ltrim(rtrim(pv.field#2)) as varchar)
when 'V' then cast(ltrim(rtrim(pv.vfield#3)) as varchar)
end
= rl.scan and pv.vend_no = rl.vendnum
***'**If statement ends*****
left join storemain..prmastp as p on p.emuserid = rl.userid
where rl.scandate between GetDate() -7 and GetDate() order by rl.scandate desc
我希望if语句只在选择的原因是'D','I'或'C'时选择描述符。如果不是我想要一个空值,因为除非原因是'D','我','C'
,否则我不会进行连接来获取该变量顺便说一句,我可以使用一个case语句,我在左连接的中间使用它。它工作得很好。那不是我的问题。
答案 0 :(得分:2)
如果您想在一个查询中使用它,则必须进行连接。使用左连接和case语句,可以确保pv.descriptor在某些情况下显示为null。
如果您想要控制流,则需要使用T-SQL
如果您关注性能,则不应加入计算值。重新思考数据库设计。您希望为连接创建新列,如果您有多对多关系,则可能需要创建中间表。
答案 1 :(得分:1)
如果pv
为v.reason
,我认为您只想加入(D, I, C)
- 是吗?如果这是您的问题,只需将您的JOIN
条款更改为:
LEFT JOIN table3 as pv ON
LTRIM(RTRIM(
CASE rl.scantype
WHEN 'S' THEN pv.field#1
WHEN 'U' THEN pv.field#2
WHEN 'V' THEN pv.field#3
END
)) = rl.scan
AND rl.vendnum = pv.vend_no
AND rl.reason IN ('D', 'I', 'C')
当然,你也有“if语句选择pv.descriptor只有在SELECT子句中有('D','I','C')[as] pv.descriptor”。所以,假设你想要那个,试试这个:
SELECT
/* your other columns */
CASE
WHEN rl.reason IN ('D', 'I', 'C') THEN pv.descriptor
ELSE NULL --optional, since it'll default to NULL
END as descriptor
答案 2 :(得分:0)
两个查询组合的动机是什么?加入可能会导致需要完全不同的评估计划...根据变量值(或更糟糕的 - 列!)在两个计划之间进行选择不是查询优化器能够做得好的。
如果您编写两个查询并使用SQL IF语句将控制权流向其中一个,那么您将会好得多。
编辑:如果rl有两行,查询应该返回什么,一行有reason = D,另一行有reason = S?
答案 3 :(得分:0)
我会保持简单,以便将来支持您的代码的人可以弄清楚如何维护它(例如,当他们添加其他原因代码时)。
它可能不那么高效,但它更易于维护。
另外,有没有办法可以在表格中获取这些代码并测试标记,而不是在sql中对它们进行硬编码?