sql排除某些结果

sql排除某些结果,sql,Sql,假设我有一个 A B -- -- a 1 b 1 c 1 d 1 d 2 e 1 f 1 f 2 g 1 如果B列中的值为1和2,且a列中的值相同,那么如何排除B列中的结果(共1列) 我希望我的结果是这样的 A B -- -- a 1 b 1 c 1 d 2 e 1 f 2 g 1 在这里显式检查值1和2,并使用正好有两个值的事实。如果可以安全地假设您总

假设我有一个

A   B
--  --
a   1  
b   1  
c   1  
d   1  
d   2  
e   1  
f   1  
f   2  
g   1  
如果B列中的值为1和2,且a列中的值相同,那么如何排除B列中的结果(共1列)

我希望我的结果是这样的

A   B  
--  --
a   1  
b   1  
c   1  
d   2  
e   1  
f   2  
g   1

在这里显式检查值1和2,并使用正好有两个值的事实。如果可以安全地假设您总是想要最高的值,那么您可能会减少此操作的麻烦

select
  tbl.A,
  tbl.B
from
  Table1 tbl
  left outer join (
    select
      A
    from
      Table1
    where
      B in (1,2)
    group by
      A
    having
      count(B) = 2
  ) mlt on tbl.A = mlt.A
where
  (
    mlt.A is not null 
    and tbl.B = 2
  ) or (
    mlt.A is null 
    and tbl.B = 1
  )
  • 计算出同时具有1和2的所有A值
  • 将这些值与A值上的表相匹配
  • 如果子查询中有A,则使用B=2记录。如果不是,则使用B=1记录

  • 对于示例数据和所需结果,实现结果的最简单查询是
    groupby
    操作和聚合函数

      SELECT d.A
           , MAX(d.B) AS B
        FROM my_data_set d
       GROUP BY d.A
       ORDER BY d.A
    
    如果我们只对列
    B
    中有
    1
    2
    的行感兴趣,我们可以添加
    WHERE
    子句

      SELECT d.A
           , MAX(d.B) AS B
        FROM my_data_set d
       WHERE d.B IN (1,2)
       GROUP BY d.A
       ORDER BY d.A
    
    对于示例数据,输出是相同的

    这两个语句都达到了指定的结果。(对于
    a
    中的每个不同值,只返回一行)


    或者,对于相同的示例数据,我们可以返回相同的结果集,并使用规范的更字面的实现

    当有一行
    2
    a
    的值相同时,要排除
    1
    行,我们可以使用
    不存在
    谓词和相关子查询

     SELECT d.A
          , d.B
       FROM my_data_set d
      WHERE ( d.B = 2 )
         OR ( d.B = 1 AND 
                NOT EXISTS ( SELECT 1
                               FROM my_data_set e
                              WHERE e.A = d.A
                                AND e.B = 2
                           )
            )
      ORDER BY d.A, d.B
    

    您最有可能使用
    EXISTS
    。1,2是固定值吗?我们能有3个吗?在a,1B,1C,1D,1D,2E,1F,1F,2G,1F下面的数据集上不能用,3@sumit:正如我在回答开始时所说,我的建议适用于问题中给出的“示例数据和期望结果”。您完全正确地指出,给定一个不同的数据集,查询的返回将是不同的。(事实上,我的答案中的第二个查询将返回答案中指定的结果,因为您的评论中提出了数据集。)问题中并未真正指定(这是不明确的)当给定不同的数据集时应返回什么结果。
    select 
    * from tbl where a IN 
    (
    
    select 
    
    a from tbl 
    group by a
    having count(*)>1
    )
    and b!=1
    
    UNION ALL
    
    select 
    * from tbl where a IN
     (
    
    select 
    
    a from tbl 
    group by a
    having count(*)=1
     )