【问题标题】:select from where field not equal to field in other table从中选择字段不等于其他表中的字段
【发布时间】:2020-05-03 07:24:58
【问题描述】:

我在 SQLite3 中运行以下脚本:

drop table if exists B;
drop table if exists C;

create table B (a integer, b text, c text);

insert into B values (1, "1.1", "B");
insert into B values (1, "2.1", "B");
insert into B values (3, "3.1", "B");
insert into B values (4, "4.1", "B");
insert into B values (5, "5.1", "B");
insert into B values (6, "6.1", "B");
insert into B values (7, "7.1", "B");

create table C (a integer);

insert into C (a) values (1), (3), (5);

select * from B where B.a <> C.a;

这个脚本在我运行时抛出一个错误:

错误:第 30 行附近:没有这样的列:C.a

这里的想法是我想从B 中进行选择,其中a 字段 等于 1、3 或 5。是否无法引用来自同一 SQL 语句中的其他表?如何做到这一点?

预期结果

a|b|c
4|"4.1"|"B"
6|"6.1"|"B"
7|"7.1"|"B"

【问题讨论】:

  • SELECT * FROM B WHERE a NOT IN (SELECT a FROM C)
  • 这似乎行得通...你知道这个查询是否可以在 Microsoft Access 中构建?
  • 这是标准 SQL 但我不使用 MS Access 来确定。
  • 您为什么不发表您的评论作为答案?我很乐意接受。
  • 附带说明:字符串文字的标准分隔符是单引号 ('),而不是双引号 (")。双引号用于包含特殊字符的别名(例如select count(*) as "number of rows" from ...)。在某些情况下,如果将两者混淆,您可能会得到不需要的结果(例如:where key = "description" 会将列键的内容与列描述的内容进行比较,而不是与字符串“描述”,如果存在具有该名称的列)。

标签: sql sqlite


【解决方案1】:

这个需求可以用NOT EXISTS这样表达:

select * from B 
where not exists (
  select 1 from C
  where C.a = B.a
);

对于B 的每一行,如果C 中不存在B.a,则NOT EXISTSTRUE,并返回该行。

或者使用LEFT JOIN,只返回不匹配的B行:

select B.*
from B left join C
on C.a = B.a
where C.a is null;

请参阅demo
结果:

| a   | b   | c   |
| --- | --- | --- |
| 4   | 4.1 | B   |
| 6   | 6.1 | B   |
| 7   | 7.1 | B   |

【讨论】:

    【解决方案2】:

    SELECT * FROM B WHERE a NOT IN (SELECT DISTINCT a FROM C)

    这是标准 SQL。

    NOT IN 排除所选集中的所有值。该集合可以来自另一个表,不一定是常量值列表。

    DISTINCT 是可选的,但它可能会在非常大的集合中产生更快的执行速度。

    【讨论】:

    • 一般推荐使用DISTINCTIN。 SQL 旨在表达我们想要的,而不是 DBMS 将如何实现这一点。在这种情况下,我们希望所有 B 行的 A 值不在 C 的 A 值集合中。 DBMS 是否在片场使用DISTINCT 来执行此操作,应该由它自己决定。它通常最清楚如何查找数据。
    • INNOT IN 指的是集合。根据定义,集合由不同的值组成。但是,SQL 引擎不可能总是知道内部的SELECT 将被用作一个集合来自动为您做DISTINCT。无论如何,它肯定不会伤害,只有在有帮助的情况下才会有所帮助。 (您对“不推荐”有一些参考吗?为什么?)
    猜你喜欢
    • 2014-08-17
    • 2014-07-16
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多