从另一个 Case 语句引用 Case 语句中的标识符

Posted

技术标签:

【中文标题】从另一个 Case 语句引用 Case 语句中的标识符【英文标题】:Referencing identifier in Case statement from another Case statement 【发布时间】:2015-07-16 14:33:49 【问题描述】:

所以我有一个看起来像这样的案例陈述:(编辑的实际报告代码)

select
     case
        when t1.reportcode in ('x', 'y', 'z') then 'AFMC'
        when t2.reportcode in ('x', 'y', 'z') then 'AFMC'
        when t1.reportcode in ('x', 'y', 'z') then 'FOH'
        when t2.reportcode in ('x', 'y', 'z') then 'FOH'
        when t1.reportcode in ('x', 'y', 'z') then 'Forest Service'
        when t2.reportcode in ('x', 'y', 'z') then 'Forest Service'
        when t1.reportcode in ('x', 'y', 'z') then 'HHS-Strive'
        when t2.reportcode in ('x', 'y', 'z') then 'HHS-Strive'
        when t1.reportcode in ('x', 'y', 'z') then 'NASA'
        when t2.reportcode in ('x', 'y', 'z') then 'NASA'
        when t1.reportcode in ('x', 'y', 'z') then 'VA SLC'
        when t2.reportcode in ('x', 'y', 'z') then 'VA SLC'
        when t1.reportcode in ('x', 'y', 'z') then 'ABMC'
        when t2.reportcode in ('x', 'y', 'z') then 'ABMC'
        when t1.reportcode in ('x', 'y', 'z') then 'DFAS'
        when t2.reportcode in ('x', 'y', 'z') then 'DFAS'
        when t1.reportcode in ('x', 'y', 'z') then 'DON'
        when t2.reportcode in ('x', 'y', 'z') then 'DON'
     end as FirstGroups,

它会检查所有这些代码并在代码匹配时为其提供一个标识符(ABMC、AFMC 等)。

在此之后,我有另一个看起来像这样的 case 语句:

case
        when 'ABMC' not in FirstGroups then 'ABMC N/A'
        when 'AFMC' not in FirstGroups then 'AFMC N/A'
        when 'DFAS' not in FirstGroups then 'DFAS N/A'
        when 'DON' not in FirstGroups then 'DON N/A'
        when 'FOH' not in FirstGroups then 'FOH N/A'
        when 'Forest Service' not in FirstGroups then 'Forest Service N/A'
        when 'HHS-Strive' not in FirstGroups then 'HHS-Strive N/A'
        when 'NASA' not in FirstGroups then 'NASA N/A'
        when 'VA SLC' not in FirstGroups then 'VA SLC N/A'
 end as NotApplicable,

这里的目标是查看我从第一个 case 语句中得到的输出,如果其中一个标识符(如“VA SLC”或“ABMC”在其中,那么它会将它在自己的列中显示“VA SLC N/A”、“ABMC N/A”等...不幸的是,我无法在第二个案例语句的第一个案例语句中引用该 FirstGroups 标识符。我也尝试过使用 t1.reportcode 和 t2.reportcode,但这些都不起作用。

预期的输出如下所示:

FirstGroups            NotApplicable
ABMC                   AFMC N/A
DFAS                   NASA N/A
DON
FOH
Forest Service
NASA
VA SLC

或类似的东西。

如果您对我如何做到这一点有任何想法,请告诉我。谢谢!

【问题讨论】:

“不在”这里应该做什么? FirstGroups 是一个标量值,所以它与这里的不等于相同,这意味着您只能得到 'ABMC N/A' 或 'AFMC N/A' - 其余情况永远无法达到? 在第二种情况下引用第一种情况的别名是重复的of this question;但这似乎只是问题的一部分。 好吧,目的是检查 FirstGroups 案例输出列中是否包含“ABMC”或其他任何内容。如果该列中没有任何内容,则应在另一列中输出“ABMC N/A”等。听起来在这里使用“不在”是不正确的。 不在任何行的列中?您可以分析地做到这一点,但您仍然只会为整个集合(或分区)显示一个 N/A 值。也许显示带有实际(假)数据和预期结果的简化版本会有所帮助。虽然……你实际问的问题已经回答了? Here's a slightly simplified demo 表明我的意思;第一种情况的所有条件(在内联视图中)都得到满足,但只有第二种情况(在外部查询中)的前两个条件得到满足。 【参考方案1】:

not in FirstGroups 建议您尝试将该列中的所有值视为一个集合,并从所有组的列表中排除该集合的成员以形成第二列;这与同一行的第一列中的值无关。您的示例输出似乎支持这一点。

这似乎是客户端应该处理的事情 - 您查询以获取第一组,并知道(或单独查询)所有组的列表,并让客户端适当地显示。

你可以用 SQL 来做,只是有点乱,尤其是不能使用 CTE。

这使用了两个内联视图;第一个获取您已经拥有的firstgroups 值,尽管我根据您的预期输出添加了一个不同的值;第二个通过使用您的固定组名列表并排除firstgroups 中的组名来获取不适用的值。不幸的是,因为您不能使用 CTE,这意味着重复您的原始案例陈述来进行排除。

这些内联视图中的每一个都添加了一个分析排名列,因此您示例中的 firstgroups 获得排名 1-7 的行,第二个获得排名 1-2 的行。

这两个内联视图然后以该等级作为连接条件进行外部连接。

select fg.groupname as firstgroups, na.notapplicable
from (
  select groupname, dense_rank() over (order by groupname) as rnk
  from (
    select distinct case
        when t1.reportcode in (1, 2, 3) then 'AFMC'
        when t1.reportcode in (4, 5, 6) then 'FOH'
        when t1.reportcode in (7, 8, 9) then 'Forest Service'
        when t1.reportcode in (10, 11, 12) then 'HHS-Strive'
        when t1.reportcode in (13, 14, 15) then 'NASA'
        when t1.reportcode in (16, 17, 18) then 'VA SLC'
        when t1.reportcode in (19, 20, 21) then 'ABMC'
        when t1.reportcode in (22, 23, 24) then 'DFAS'
        when t1.reportcode in (25, 26, 27) then 'DON'
      end as groupname
    from t1
  )
) fg
full outer join (
  select column_value || ' N/A' as notapplicable,
    dense_rank() over (order by column_value) as rnk
  from table(sys.odcivarchar2list('ABMC', 'AFMC', 'DFAS', 'DON', 'FOH',
    'Forest Service', 'HHS-Strive', 'NASA', 'VA SLC')
  ) allgroups
  where not exists (
    select 1
    from (
      select case
        when t1.reportcode in (1, 2, 3) then 'AFMC'
        when t1.reportcode in (4, 5, 6) then 'FOH'
        when t1.reportcode in (7, 8, 9) then 'Forest Service'
        when t1.reportcode in (10, 11, 12) then 'HHS-Strive'
        when t1.reportcode in (13, 14, 15) then 'NASA'
        when t1.reportcode in (16, 17, 18) then 'VA SLC'
        when t1.reportcode in (19, 20, 21) then 'ABMC'
        when t1.reportcode in (22, 23, 24) then 'DFAS'
        when t1.reportcode in (25, 26, 27) then 'DON'
      end as groupname
      from t1
    ) firstgroups
    where firstgroups.groupname = allgroups.column_value
  )
) na
on na.rnk = fg.rnk
order by coalesce(fg.rnk, na.rnk);

得到:

FIRSTGROUPS          NOTAPPLICABLE      
-------------------- --------------------
ABMC                 AFMC N/A            
DFAS                 NASA N/A            
DON                                      
FOH                                      
Forest Service                           
HHS-Strive                               
VA SLC                                                            

SQL Fiddle demo。我已经编写了报告代码值来匹配您显示的内容。

使用 CTE 会短一些:

with firstgroups as (
  select groupname, dense_rank() over (order by groupname) as rnk
  from (
    select distinct case
        when t1.reportcode in (1, 2, 3) then 'AFMC'
        when t1.reportcode in (4, 5, 6) then 'FOH'
        when t1.reportcode in (7, 8, 9) then 'Forest Service'
        when t1.reportcode in (10, 11, 12) then 'HHS-Strive'
        when t1.reportcode in (13, 14, 15) then 'NASA'
        when t1.reportcode in (16, 17, 18) then 'VA SLC'
        when t1.reportcode in (19, 20, 21) then 'ABMC'
        when t1.reportcode in (22, 23, 24) then 'DFAS'
        when t1.reportcode in (25, 26, 27) then 'DON'
      end as groupname
    from t1
  )
)
select fg.groupname as firstgroups, na.notapplicable
from firstgroups fg
full outer join (
  select column_value || ' N/A' as notapplicable,
    dense_rank() over (order by column_value) as rnk
  from table(sys.odcivarchar2list('ABMC', 'AFMC', 'DFAS', 'DON', 'FOH',
    'Forest Service', 'HHS-Strive', 'NASA', 'VA SLC')
  ) allgroups
  where not exists (
    select 1
    from firstgroups
    where firstgroups.groupname = allgroups.column_value
  )
) na
on na.rnk = fg.rnk
order by coalesce(fg.rnk, na.rnk);

SQL Fiddle demo 获取信息,因为您似乎不适合在您的 SSIS 版本中使用此语法。

【讨论】:

以上是关于从另一个 Case 语句引用 Case 语句中的标识符的主要内容,如果未能解决你的问题,请参考以下文章

case语句用法 case语句怎么用

C语言 回滚技术 switch case

C语言中的Switch-case语句

delphi中的case of语句

Case 语句中的 select 语句

MYSQL中的Case语句,没有找到Case?