代码之家  ›  专栏  ›  技术社区  ›  Henry Yang

能否在SQL SELECT语句中将表用作列?

  •  5
  • Henry Yang  · 技术社区  · 6 年前

    我正在使用其他人的代码,看到了一些我不了解的Oracle SQL的用法:

      SELECT
        column1, column2,
        (
          SELECT columnA
          FROM tableA
          JOIN tableB ON tableA.table_b_fk = tableB.my_pk
          FETCH FIRST 1 ROWS ONLY
        ) AS column3
      FROM tableC
      ...
    

    我很难理解他们为什么使用这个:

    (
      SELECT columnA
      FROM tableA
      JOIN tableB ON tableA.table_b_fk = tableB.my_pk
      FETCH FIRST 1 ROWS ONLY
    ) AS column3
    

    他们只是用一个表作为列吗?我以为你只能使用列?

    你真的能做到吗?它是如何工作的?

    我不知道在哪里可以找到这个用法的解释,所以我在这里问。

    如果有任何误解,请纠正我!

    1 回复  |  直到 6 年前
        1
  •  3
  •   Lukasz Szozda    6 年前

    首先,我不认为您所介绍的代码实际有效:

    SELECT
        column1, column2,
        (
          SELECT columnA, columnB
          FROM tableA
          JOIN tableB ON tableA.table_b_fk = tableB.my_pk
          FETCH FIRST 1 ROWS ONLY
        ) AS column3
    FROM tableC
    

    基本上与以下内容相同:

    SELECT 1 AS c
       , (SELECT 'a', 'b' FROM dual)
    FROM dual
    -- and will yield
    -- ORA-00913: too many values
    

    您看到的构造是 标量子查询 在选择列表中(它本身不是一个表)。它必须返回一行和一个值(因此 FETCH FIRST 1 ROWS ONLY )。

    SELECT 1 AS c
       , (SELECT 'a' FROM dual)  -- one column and one value subquery
    FROM dual
    

    如果要在外部查询中每行返回多个列,可以使用 CROSS/OUTER APPLY :

    SELECT column1, column2, s.*
    FROM tableC
    OUTER APPLY (SELECT columnA, columnB
                 FROM tableA
                 JOIN tableB ON tableA.table_b_fk = tableB.my_pk
                 FETCH FIRST 1 ROWS ONLY) s
    

    仍然要使事情正确,它应该是相关的子查询。更多信息: