代码之家  ›  专栏  ›  技术社区  ›  bobobobo

选择不存在的内容

  •  1
  • bobobobo  · 技术社区  · 14 年前

    我有这张桌子。我想选择回不存在的项目,以便创建它们。

    table tags
    +---------+-------+
    | tagId   | name  |
    |   1     | C     |
    |   2     | DX    |
    |   3     | CG    |
    

    假设SQL看起来像:

    select name from tags where name in ( 'C', 'CG', 'RX' )
    

    你回来了 'C' 'CG' ,所以你知道你必须创造 'RX' .

    有没有办法让这样的mysql语句返回 “RX” 相反,当 “RX” 不存在?

    2 回复  |  直到 14 年前
        1
  •  4
  •   luke    14 年前

    假设您的标签(‘C’、‘CG’、‘RX’)位于一个名为“标签”的表中,与上面的结构相同。

    然后你可以这样做:

    select tr.name 
    from tags as tl 
        right join tags_match as tr 
        on tl.name = tr.name
    where tl.name is null
    

    这将找到标记中所有不在标记中的项目,因此这将为您提供所需的结果,但不幸的是,您的标记(“C”、“CG”、“RX”)不在表中:(

    不管我们是否可以使用子查询来“伪造”表

    select tr.name 
    from tags as tl 
        right join (select 'cg' as name 
                    union select 'c' as name 
                    union select 'rx' as name) as tr 
        on tl.name = tr.name
    where tl.name is null
    

    虽然有点难看,但这是可行的。如果您有许多要测试的项目,您可能会考虑创建一个真正的临时表。

        2
  •  1
  •   amphetamachine    14 年前

    当然!

    select name from tags where name not in ( 'C', 'CG', 'RX' )
    

    唯一的问题是,如果 not in 列表很长,此查询将很慢,因为它必须根据每行的 'name' 字段以确定它是否不在列表中,而不是 in 如果匹配,它将停止检查该点的列表并返回该行。


    编辑: 上述解决方案是错误的。我很抱歉。真正的解决方案如下。

    以下是您在一行SQL中的操作方法:

    select name from (
        select "C" as name
        union select "CG"
        union select "RX"
    ) as foo
    where name not in (select name from tags);