【问题标题】:SQL 'belong to' logicSQL“属于”逻辑
【发布时间】:2018-08-10 05:30:14
【问题描述】:

所以,我一直在尝试用 SQL 编写查询,但遇到了一个问题。我正在尝试写一种“属于”的条件。我想要做的是,如果要获取的值属于另一个表中的列,则填充一件事,否则填充 null。
例如。

NAME table
ID    NAMES
1      A
2      B
3      C
4      D
5      E

XYZ table
ID
2
4
5

我写了这样的查询

(CASE WHEN NAME.ID IN (SELECT ID FROM XYZ) THEN NAME.NAMES ELSE NULL END ) AS 'ABC'

这个查询确实运行了,但它已经运行了 14 个小时(显​​然是为了大量的数据),但仍然没有结果。这个逻辑有什么缺陷还是有更好的方法可以做到?

我希望得到这样的结果:

ABC
NULL
B
NULL 
D
E

【问题讨论】:

  • 您使用的是哪个 RDBMS?
  • 我总是尽量避免选择列表中的子查询。我会在 Name.ID 上离开 join 到 XYZ,然后在你的 case 语句中的关键字段上检查是否为空。至少我是这么认为的,你的问题并不太清楚。

标签: sql logic belongs-to


【解决方案1】:

你只需要一个简单的左连接:

SELECT
    CASE WHEN t2.ID IS NOT NULL THEN t1.NAMES END AS ABC
FROM NAME t1
LEFT JOIN XYZ t2
    ON t1.ID = t2.ID;

Demo

请注意,CASE 表达式 else 条件,如果未明确指定,则默认为 NULL。此行为在这里有效,因为如果NAME 表中的给定记录与XYZ 表中的任何记录匹配,您想要呈现NULL

【讨论】:

  • 感谢蒂姆,工作就像奇迹。但是你能告诉我我的逻辑有什么问题吗?我想知道出了什么问题以及为什么。
【解决方案2】:

问题不在于你的逻辑。这只是代码的优化方式。子查询可能正在为外部查询中的每一行运行。

我建议切换到exists

(case when exists (select 1 from xyz where xyz.id = name.id) then name.names
 end) as abc

这会维护原始查询的语义。特别是,xyz 中的重复项不会返回多行(left join 会发生这种情况)。

为了性能——或left join——你需要一个xyz(id)上的索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    相关资源
    最近更新 更多