【问题标题】:Hierarchical vs. Short-Circuit assignment in SQL?SQL中的分层与短路分配?
【发布时间】:2012-12-26 14:29:58
【问题描述】:

SQL 是否同时具有短路和分层多重评估语法?

短路分配示例。这里decision 在 ... 为真时获取 FIRST *** 子句:

短路

   case  
     when (...) then (***) 
     when (...) then (***)
     when (...) then (***)
     else (...)
   end as decision

分层分配示例。这里decision 在 ... 为真时获取 LAST *** 表达式。

分层

    if (...) then (decision = ***) end
    if (...) then (decision = ***) end
    if (...) then (decision = ***) end

相互转化

很明显,颠倒表达式的顺序会在分层和短路之间切换。我想知道 SQL 是否也有一个可以分配 LAST tr 表达式的构造?

测试用例:

下面给出一个非常简单的玩具例子:

select 
  flag1, flag2, flag3,
  case
     when flag1=1 and flag2=0 then 'LEFT'
     when flag1=0 and flag2=0 then 'NONE'
     when flag2=0 and flag3=1 then 'RIGHT'
  end as decision 
FROM 
( select 
  1 as flag1, 0 as flag2, 1 as flag3
  -- from dual                               -- if you use Oracle
) tmp ;

短路 SQL 将返回 'LEFT'

分层分配将返回“RIGHT”。

编辑:您可以通过单击链接在SQL-Fiddle 中运行此示例。 (感谢 ypercube 指出这个有用的网站!(+1))

【问题讨论】:

  • 最后一个例子很好(但它会在 SQL 中出错)。
  • @ypercube:我在 Teradata SQL 中成功运行它并验证它给出了 LEFT。然后在 flag1 设置为 0 的情况下再次运行它,它返回 NONE... 这肯定证实了 SQL 的 case/when 构造是短路的。你用什么 SQL 运行它?它给了你什么错误?
  • 试试 SQL-Fiddle 所有 4 个 DBMS(SQL-Server、Postgres、Oracle、MySQL)都会导致错误(您的查询是第二个)。跨度>
  • @AKE 对于oracle,您缺少from table..
  • 嗯,你说得对。显然,Teradata 在接受的方面相当随和!太糟糕了,SQL-Fiddle 中没有 Teradata 选项。我将编辑该示例,使其在 SQL-Fiddle 中工作。

标签: sql tsql conditional conditional-statements teradata


【解决方案1】:

对于 SQL,这不是很重要,因为您最终在 CASE WHEN 子句中只有一个值。所以你需要做的就是重新安排你的条件。

在其他语言中,您执行一些存储在变量等中的计算,而在 pure SQL 中并非如此。

【讨论】:

  • 我读了这个问题。您打算如何在纯 SQL 中为变量赋值?这就是为什么这个问题与 SQL 无关或者你需要让它更清楚的原因。
  • 你关于变量的观点很好,但我已经知道了——问题很清楚:寻找 SQL 是否具有可以进行分层评估的构造。见巴萨姆的回答。 (仅供参考——有时这完全取决于你怎么说,所以“无关紧要”可能只是意味着你看不到重点或解决方案......)
  • 如果您可以重新排列 SQL,我仍然看不到分层评估的意义。它将为您提供相同的结果,因此 SQL 是否具有它无关紧要。 “无关紧要”并不是我粗鲁的意思,只是让它听起来更好听并不重要。
  • 没有意义——我很想知道 SQL 作为一种语言是否具备这种能力。务实地说,重新安排是明确的,所以这不是问题。 Bassam 的回答表明,SQL 与任何其他编程语言在它可以做的事情上没有什么不同——这就是我所追求的。无论如何,谢谢你的cmets。干杯
  • 好的,我明白了。我认为如果您在问题中提到 PL/SQL 或 T-SQL,那么它会更有意义。我对 SQL 很狂热,抱歉)
【解决方案2】:

没有表达式可以在一次选择中进行分层赋值,但它可以像任何其他编程语言一样通过多个 if 语句来实现

DECLARE @flag1 BIT = 1, @flag2 BIT = 0, @flag3 BIT = 1, @decision VARCHAR(50)

IF @flag1 = 1 AND @flag2 = 0
    SET @decision = 'LEFT'

IF @flag1 = 0 AND @flag2 = 0
    SET @decision = 'NONE'

IF @flag2 = 0 AND @flag3 = 1
    SET @decision = 'RIGHT'

SELECT @decision

【讨论】:

  • @AKE 没问题,很高兴我能帮上忙!
  • 但如果您只有一行,这将起作用。它不适用于表格。
猜你喜欢
  • 1970-01-01
  • 2022-08-04
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 2019-09-19
  • 2010-09-20
  • 2015-10-28
相关资源
最近更新 更多