代码之家  ›  专栏  ›  技术社区  ›  Choppy The Lumberjack

在左联接期间检查整行为空

  •  1
  • Choppy The Lumberjack  · 技术社区  · 7 年前

    我有以下观点,可以作为另一个系统的接口。请注意,它是一个视图,而不是一个表,因此我无法更改架构并添加主键。

    view NODE (
        STATE varchar(255), -- can be null
        SIBLING_STATE varchar(255) -- can also be null
    )
    

    然后,我需要将这个表连接到SIBLING\u STATE列上的表本身,以查找具有该状态的所有其他节点。

    select n.STATE, n.SIBLING_STATE, ns.STATE from NODE n
    left join NODE ns where n.SIBLING_STATE = ns.STATE
    

    然后,我需要将这一点传递给其他进行分组和计数的观点,但所有这些都与讨论无关。

    我遇到的问题是,作为第二个要求,我需要检查是否由于此连接而实际检索到了任何同级记录,但如上所述,任何节点的 STATE 和/或 SIBLING_STATE 可以为null。

    select 
        n.STATE, 
        n.SIBLING_STATE, 
        ns.STATE,
        case when (ns.<something> is not null) then 'found' else 'not found' end as IS_FOUND 
    from NODE n
    left join NODE ns where n.SIBLING_STATE = ns.STATE
    

    如何实际检查 ns 记录是否存在?我不能空检查 ns.STATE ns.SIBLING_STATE 因为它们本身都可以为null:

    -- Can't do this because ns.SIBLING_STATE might be null 
    case when (ns.SIBLING_STATE is not null) then 'found' else 'not found' end as IS_FOUND
    -- Can't do this because ns.STATE might be null
    case when (ns.STATE is not null) then 'found' else 'not found' end as IS_FOUND
    

    有没有关于如何对整个记录进行空检查的想法,例如,如果我可以这样说?

    case when (recordExists(ns)) then 'found' else 'not found' end as IS_FOUND
    

    任何类型的答案,包括特定方言的答案(即仅适用于mysql/sql server/postgresql)都将不胜感激。

    编辑:澄清这是一个视图

    3 回复  |  直到 7 年前
        1
  •  1
  •   RBarryYoung    7 年前

    像这样

    select 
        n.STATE, 
        n.SIBLING_STATE, 
        ns.STATE,
        case when (ns.NeverNull is not null) then 'found' else 'not found' end as IS_FOUND 
    from NODE n
    left join From (Select *, 'A' As NeverNull From NODE) ns 
       ON n.SIBLING_STATE = ns.STATE
    
        2
  •  0
  •   Gordon Linoff    7 年前

    您需要修复数据结构,以便拥有主键。您没有指定数据库,但典型的语法可能是:

    create table NODE (
        NODE_ID int auto_increment primary key
        STATE varchar(255), -- can be null
        SIBLING_STATE varchar(255) -- can also be null
    );
    

    (我任意使用了MySQL语法。)

    然后您可以简单地使用该值:

    select n.STATE, n.SIBLING_STATE, ns.STATE,
           (case when ns.nod_id is not null then 'found' else 'not found' end as IS_FOUND 
    from NODE n left join
         NODE ns 
         on n.SIBLING_STATE = ns.STATE;
    

    备注:

    • 作为问题解决方案的一部分,这似乎是一个非常尴尬的步骤。你可能想问另一个问题,关于你真正想解决的问题的更多方面。
    • 所有表都应具有标识/自动递增/串行主键。
    • 尤其是,表不应包含列,所有列都可以是 NULL 在多行上。事实上,即使值不是 无效的
    • JOIN s应始终具有 ON 条款
        3
  •  0
  •   Funk Forty Niner    7 年前

    这是你的期望吗?如果我理解正确。

    当您使用 LEFT JOIN 您需要使用 ON 我喜欢两张桌子。

    select  
        n.STATE, 
        n.SIBLING_STATE, 
        ns.STATE,
        ns.SIBLING_STATE,
        case 
          when ns.SIBLING_STATE is null or ns.STATE  is null 
          then 'not found' 
          else 'found' 
        end as IS_FOUND 
    from NODE n
    LEFT join NODE ns ON n.STATE = ns.SIBLING_STATE
    

    小提琴: http://sqlfiddle.com/#!9/47af63/2