【问题标题】:Select a record that needs to satisfy two conditions but they are actually two records in the same table选择一条需要同时满足两个条件但实际上是同一张表中的两条记录的记录
【发布时间】:2015-12-11 20:19:21
【问题描述】:

考虑这种情况: 表:

Code    Lang
123 En
123 De
345 De

考虑这个表,其中代码有两个不同的语言 EN 和 DE。 我想显示该表中的记录,其中代码只有“DE”但没有“EN” 如何做到这一点?

【问题讨论】:

  • 请标记一个数据库引擎
  • db 对于这个问题不是必需的。我认为这个问题可以用 ansi-sql 命令解决。

标签: mysql sql sql-server oracle


【解决方案1】:

您可以使用exceptminus,具体取决于所使用的数据库。

select code from table
where lang = 'DE'
except --in sql server --minus in oracle
select code from table
where lang <> 'DE'

【讨论】:

    【解决方案2】:

    如果有一组您不想显示的语言列表,

    Select Code, Lang
    Where Lang <> 'DE'
    

    【讨论】:

    • 假设要匹配问题,您的子句将是 Lang 'EN',这甚至仍然包括可能同时具有 'DE' 和 'EN' 的记录,因为您只是排除了一个特定的一组值。问题是“显示代码只有'DE'但没有'EN'的记录,这与仅过滤掉某些记录略有不同。如果将其用作不存在或不存在类型的子查询,这将很好用连同一个更大的声明,但肯定不是独立的。
    • 谢谢你。今天早上当我回答这个问题时,我正处于思绪之中,并且误读了这个问题。我会删除我的答案,但您的评论为这次讨论增加了价值。
    【解决方案3】:

    对于 SQL Server,有多种方法可以解决此问题,但对于大多数引擎(包括 sql server)来说,简单的自联接将全面工作:

    select t.code, t.lang
    from   table t
    left join table t2
    on     t.code = t2.code
    and    t2.lang != 'De'
    where  t.lang = 'De'
    and    t2.code is null;
    

    其他方法(取决于数据库引擎)可能包括 where 子句中的 NOT EXISTS 子查询、EXCEPT 运算符(如@vkp 回答的那样)、where 子句中的 NOT IN 子句/子查询、OUTER APPLY(在 sql服务器)等

    如果您为我们缩小数据库引擎的范围,也许可以给出更有针对性的答案。

    【讨论】:

      【解决方案4】:

      试试这个:

      create table #test(
      code int, lang varchar(2))
      insert #test select 123, 'En'
      insert #test select 123, 'De'
      insert #test select 345, 'De'
      
         select code from #test t1
          where exists (select * from #test t2 
                         where t1.code = t2.code 
                           and t1.lang = t2.lang 
                           and t2.lang = 'De')
          and not exists (select * from #test t3 
                           where t1.code = t3.code 
                            -- and t1.lang = t3.lang  this is trick part
                             and t3.lang = 'En')
      

      结果:

      code        lang 
      ----------- ---- 
              345 De   
      

      【讨论】:

      • 实际上可以将其简化(并且在大多数引擎中可以获得更有效的计划/执行): select * from #test t2 where t2.lang = 'De' and not exists (select * from #测试 t3 其中 t2.code = t3.code 和 t3.lang = 'En');
      • 这样会更好。
      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多