【问题标题】:How to return specific values from a table如何从表中返回特定值
【发布时间】:2018-02-23 11:33:11
【问题描述】:

我需要从表中返回行,其中ID 的所有行都具有CODE 的特定值。

例如:

TABLE: A

ID   | NAME  |CODE
-----------------
101  | XXX   | A
101  | XXX   | B
101  | XXX   | C
101  | XXX   | A
102  | XXX   | B
103  | XXX   | B
104  | XXX   | D
104  | XXX   | B
105  | XXX   | A
105  | XXX   | B
105  | XXX   | D
105  | XXX   | A
106  | XXX   | B
107  | XXX   | B

我需要只有代码B 的行。所以这是上表的预期输出:

ID   | NAME  |CODE
-----------------
102  | XXX   | B
103  | XXX   | B
106  | XXX   | B
107  | XXX   | B

这里ID101、104、105 也有代码 B,但它们不应该在我的输出中返回,因为它们还有其他代码。

我可以写什么查询来获得高于输出的结果?

我还需要确保这些值不存在于另一个表 B 中。所以,我需要添加

AND NOT EXISTS (SELECT 1 FROM TABLE B WHERE B.ID = A.ID)

B表有主键ID,B表中没有Code列。我只是使用此表来消除常见的 ID,因为我需要存在于表 A 而不是表 B 中的结果。

这是

中的示例数据
Table : B 

ID  | Name  | City  | Department
------------------------------
101  | XXX   | XXX  | XX
104  | XXX   | XXX  | XX
105  | XXX   | XXX  | XX
107  | XXX   | XXX  | XX

在表 A 中,107 ID 在 Code 列中只有 B。但是,它存在于表 B 中,所以我不想在输出中返回这一行。

【问题讨论】:

  • 嗨,以下答案都不能解决我的问题,谁能帮我解决这个问题?

标签: sql oracle join subquery


【解决方案1】:

这是一种方法:

select b.id
from tableb b
group by b.id
having min(b.code) = max(b.code) and min(b.code) = 'B';

如果你明确表示没有“A”和“B”,但允许其他代码,那么你可以这样做:

select b.id
from tableb b
where b.code in ('A', 'B')
group by b.id
having min(b.code) = max(b.code) and min(b.code) = 'B';

【讨论】:

  • 对不起,如果我的问题不清楚,第二个表没有代码列。我只使用它来消除常见的 ID,因为我需要获取仅存在于表 A 中的 ID。
  • @signup 。 . .当我阅读问题时,没有 second 表:“我需要从具有某些特定代码的表中返回值。该表没有主键列。”。
  • 我已经编辑了这个问题 - 希望它更清楚,并且仍然是 @signup 的意思。
  • @Gordon-Linoff 你现在可以看一下吗?
  • @WilliamRobertson TQ:)
【解决方案2】:

另一种选择:

select id
from tableb
group by id
having sum(decode(code, 'B', 0, 1)) = 0

[修改问题后编辑]

select *
from tablea a
where a.id in (select a1.id
               from tablea a1
               group by a1.id
               having sum(decode(a1.code, 'b', 0, 1)) = 0
              )              
  and not exists (select null from tableb b where b.id = a.id) 

【讨论】:

  • 问题已编辑,您能提出新的答案吗?
  • 当然;你来了,看看,@signup。
  • 感谢您的回答,ID 101也有代码B,上面的代码会考虑这个吗?或不?如果不能,请您解释一下它是如何工作的?
【解决方案3】:

当您需要像count 这样的分组功能并且想要保留所有细节时使用分析功能。甲骨文说:

它们与聚合函数的不同之处在于它们返回多行 每个组。

这样你就可以避免两次敲桌子。还要注意正确处理nulls。

select id, name 
  from (select id, name, code, 
               count(case when code <> 'B' or code is null then 1 end) 
                     over (partition by id) cnt
          from a) a
  where cnt = 0 and not exists (select 1 from b where id = a.id)

SQL demo

【讨论】:

  • 嗨@Ponder-Stibbons,您能在选择语句中使用“*”更改代码吗?
【解决方案4】:

这是使用NOT EXISTS的解决方案:

SELECT
    ID
    ,NAME
    ,CODE
FROM tblA a
WHERE CODE = 'B'
AND NOT EXISTS (
    SELECT ID
    FROM tblA b
    WHERE CODE <> 'B'
    AND a.ID = b.ID
)
AND NOT EXISTS (
    SELECT ID
    FROM tblB c
    WHERE a.ID = c.ID 
)

【讨论】:

  • 问题已编辑,您能提出新的答案吗?
  • 你应该更具体一点,并为表 B 放一些示例数据
  • 嗨@Valerica,现在我修改了问题,你可以看看吗?
  • @signup 完成,我已更改查询。
猜你喜欢
  • 2022-12-16
  • 2018-10-02
  • 1970-01-01
  • 2017-10-31
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
相关资源
最近更新 更多