【问题标题】:SQL in clause with dummy rows带有虚拟行的 SQL in 子句
【发布时间】:2010-08-27 14:00:29
【问题描述】:

我真的很想知道是否可以执行一个 select 语句,它返回完全相同的记录,我们放入 in 子句?

示例:

select * from table
where table_id in (1, 2, 3, 666);

这个表的例子只有 id-s 从 1 到 100,所以这个选择将只返回三行。我需要做什么,才能为 666 获得一个(可能为 null 或虚拟)行?

谢谢!

【问题讨论】:

    标签: sql in-clause dummy-data


    【解决方案1】:

    你可以使用联合:

    select * from table
    where table_id in (1, 2, 3);
    union
    select 666 as table_id, other_fields_with_dummy_values_in_table from dual;
    

    是您在 Oracle 中如何做到的。 from dual 可能会因您使用的数据库系统而异。

    请注意,如果您使用联合,您的虚拟查询必须选择与真实查询相同的记录。

    【讨论】:

    • 您的解决方案要求您在定义语句时知道哪些值在表中,哪些不在表中。
    • @Frank:好吧,如果你想以编程方式设置它,你可以使用动态 SQL 来构建虚拟列表,但是 OP 谈论它的方式,在我看来他们已经知道了什么需要提前成为一个假人。但是,是的,我猜这可能需要一些澄清。
    【解决方案2】:

    您可以不使用表格进行选择

    只需对您的查询做一个 UNION

    select table_id, some_column from table
    where table_id in (1, 2, 3, 666);
    union
    select 666, 'dummy_data'
    

    【讨论】:

      【解决方案3】:

      假设一个表 numbers 包含从 1 到 1000000 的所有数字(实际上足以覆盖您的输入值范围),您可以运行以下 SQL:

      SELECT *
        FROM numbers left outer join table on table.table_id = numbers.number
       WHERE numbers.number in (1, 2, 3, 666)
      

      如果您使用提供更好解决方案的 DBMS,例如 e. G。 SQL Anywhere 带有它的sa_rowgenerator 过程,您可以将表numbers 替换为过程调用,并且没有最大数量的限制。

      【讨论】:

      • 在他需要一个不在numbers.number 中的虚拟值之前,这将起作用。
      • 是的,这是一个限制 - 至少对于许多 DBMS 而言,但 e. G。 SQL Anywhere 提供了一个带有系统过程的解决方案。我将其添加到我的答案中。
      【解决方案4】:

      IN 子句是布尔谓词,因此您需要将其替换为虚拟记录集:

      SELECT  m.*
      FROM    (
              SELECT  1 AS id
              UNION ALL
              SELECT  2 AS id
              UNION ALL
              SELECT  3 AS id
              UNION ALL
              SELECT  666 AS id
              ) q
      LEFT JOIN
              mytable m
      ON      m.id = q.id
      

      SQL Server 2008,你可以运行这个查询:

      SELECT  *
      FROM    @mydata d
      LEFT JOIN
              mytable t
      ON      t.id = d.id
      

      @mydate 是一个表变量,作为参数从客户端传递。

      PostgreSQL,你可以运行这个查询:

      SELECT  *
      FROM    (
              SELECT  :arr[s] AS id
              FROM    generate_series(1, array_upper(:arr, 1)) s
              ) q
      LEFT JOIN
              mytable t
      ON      t.id = q.id
      

      其中:arr 是一个数组[1, 2, 3, 666],也是从客户端作为参数传递过来的。

      Oracle,你可以这样做:

      SELECT  *
      FROM    TABLE(:mycol) q
      LEFT JOIN
              mytable t
      ON      t.id = q.id
      

      ,其中:mycol是一个集合类型的变量,从客户端传递过来。

      【讨论】:

        【解决方案5】:

        一种思考方式是:您需要将该数据作为数据集“输入”查询。在 where 子句中找到的数据永远不会“添加”到查询中,它们仅用于过滤掉现有数据。

        一个简单的例子:

        DECLARE @MustInclude (Value  int  not null)
        
        INSERT @MustInclude (Value) values (1)
        INSERT @MustInclude (Value) values (2)
        INSERT @MustInclude (Value) values (3)
        INSERT @MustInclude (Value) values (666)
        
        SELECT *
         from @MustInclude mi
          left outer join MyTable mt
           on mt.Value = mi.Value
        

        【讨论】:

          猜你喜欢
          • 2013-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-09
          • 1970-01-01
          • 2014-04-16
          • 2020-02-22
          相关资源
          最近更新 更多