【问题标题】:Create an inline SQL table on the fly (for an excluding left join)动态创建内联 SQL 表(用于排除左连接)
【发布时间】:2021-06-17 12:03:43
【问题描述】:

假设如下:

表 A

id | value
----------
1   | red
2   | orange
5   | yellow
10  | green
11  | blue
12  | indigo
20  | violet

我有一个 id 列表 (10, 11, 12, 13, 14),可用于在此表中查找 id。这个 id 列表是在我的前端生成的。

使用纯 SQL,我需要从此列表 (10, 11, 12, 13, 14) 中选择表 A 中没有条目的 id(加入“id”列)。结果应该是id的13和14的结果集。

如何仅使用 SQL 来完成此操作? (另外,如果可能的话,我想避免使用存储过程)

我能想到的唯一方法是动态创建一个内联 SQL 表来临时保存我的 id 列表。但是,我不知道该怎么做。这可能吗?有没有更好的办法?

谢谢! :)

【问题讨论】:

  • 这不是很清楚。如果您的 ID 不在另一个表中,则无需加入。
  • 没错。 :) 这就是问题所在!
  • NOT IN(<your list>) 有什么问题?
  • @Cfreak:OP 不希望表中的 id 不在列表中;他想要列表中不在表格中的 id。

标签: mysql sql rdbms


【解决方案1】:

您可以从 SQL Server 2008 开始使用表值构造函数执行此操作。

SELECT * FROM (
   VALUES(1, 'red'),
         (2, 'orange'),
         (5, 'yellow'),
         (10, 'green'),
         (11, 'blue'),
         (12, 'indigo'),
         (20, 'violet'))
   AS Colors(Id, Value)

更多信息在这里: Table Value Constructor

【讨论】:

  • 不幸的是,这个问题被标记为mysql,而不是sql-server。
  • 幸运的是我仍然点击它并找到了这个
  • 投了赞成票,因为我正在搜索 SQL Server,并且您提供了技术/功能/功能的名称,即使 OP 要求使用另一个 RDBMS。
  • 非法符号 "(".
【解决方案2】:

您可以使用UNION 子查询创建“内联表”:

(
            SELECT 10 AS id
  UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14
  -- etc.
) AS inline_table

【讨论】:

  • 如果我的列表实际上有几百个项目(而不是问题中的 5 个项目),这会是一个问题吗?
  • @rinogo:嗯,这会使您的查询变得很长(这可能意味着解析需要一段时间),但我不知道可能导致的任何固有问题。
  • @rinogo:对于非常大的列表,您可以达到max_allowed_packet 限制,这将不允许您提交查询,尽管它需要使用默认设置的数十万条记录。
  • 这正是我所需要的! PS:我对条目数量的需求非常有限:从 0 到 6,所以效果很好
  • 非法使用关键字联合。 TOKEN , FROM INTO 是预期的。
【解决方案3】:
CREATE TEMPORARY TABLE ids (id INT NOT NULL PRIMARY KEY);

INSERT
INTO    ids
VALUES
(10),
(11),
(12),
(13),
(14);

SELECT  *
FROM    ids
WHERE   id NOT IN
        (
        SELECT  id
        FROM    a
        );

【讨论】:

  • @mortezakavakebi:你什么意思?
  • 创建表不是会话库。当不同的用户调用包含此查询的 url 时,会在“ids”表上产生冲突。
  • @mortezakavakebi:来自文档:TEMPORARY 表仅对当前连接可见,并在连接关闭时自动删除。这意味着两个不同的连接可以使用相同的临时表名,而不会相互冲突或与现有的非TEMPORARY 同名表发生冲突。
  • 我有一个语法错误:CREATE TEMPORARY TABLE ids (id INT NOT NULL PRIMARY KEY);消息如下:在 CREATE、DROP 或 ALTER 语句中使用了未知对象类型“TEMPORARY”。
  • @FrenkyB:当您尝试在 SQL Server 上运行 MySQL 查询时,这很正常。
【解决方案4】:

类似的方法也可以

    
    SELECT * FROM (
    SELECT 'ds' AS source
    UNION ALL
    SELECT 'cache' AS source
    ) as dataSource
----------
| source |
----------
| ds     |
----------
| cache  |
----------



【讨论】:

    【解决方案5】:
    create table B (id int)
    insert into B values (10),(11),(12),(13),(14)
    
    select *
    from B
    left join A 
    on A.id=B.id
    where A.id is null
    
    drop table B
    

    http://sqlfiddle.com/#!6/6666c1/30

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 2016-12-13
      • 2016-11-29
      • 2020-01-26
      • 2015-01-05
      • 2014-02-12
      • 1970-01-01
      • 2010-09-16
      相关资源
      最近更新 更多