你可以在SQL SELECT语句中使用表作为一列吗?

5
我正在处理其他人的代码,发现一些我不理解的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
你确定是列A 列B 而不是列A || 列B 吗? - jjk_charles
只有ColumnA,我在问题代码中犯了一个错误。我已经进行了修正和纠正。 - Henry Yang
1
这被称为标量子查询,在SQL语句中非常常见。 - Gordon Linoff
1个回答

3

首先,我不相信你提供的代码实际上是有效的:

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

你看到的结构是SELECT列表中的标量子查询(它本身不是一个表)。它必须返回一行一列的值(因此你需要使用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

仍需使用相关子查询来使事情正确。更多信息:

只有ColumnA,我在问题代码中犯了一个错误。我已经进行了修正和纠正。 - Henry Yang
@HenryYang,正如我所写的那样,它不是表格,而是标量子查询表达式。 - Lukasz Szozda
非常感谢您的回答和提供更多信息的URL!我现在认为我理解了表达式的含义。但是,您能否为我澄清以下问题?对于第一个URL,它提到标量子查询表达式不能用作列的默认值,这是否意味着在SELECT语句中列出的列不是默认值?如果是这样,那么列的默认值是什么?此外,我看到您编写了SELECT 1 AS c,这是否意味着您想创建一个名为c的列的表,并使该表的所有行都具有值为1的c列? - Henry Yang
最后,我能否假设dual表是仅有两个元素而不是两列超过2个元素的表?因为您没有使用FETCH FIRST 1 ROWS ONLY,这意味着如果dual包含多于2个元素,则将获取多个元素,根据您的答案,这将无法形成标量子查询。 - Henry Yang
@HenryYang COLUMN的默认值 => 它与SELECT无关,而是DDL(数据定义语言)如CREATE TABLE t(i INT DEFAULT (SELECT 1 FROM dual))。你会得到错误信息“ORA-22818:不允许使用子查询表达式”。Dual伪表始终包含一行(因此我不需要任何fetch first)。SELECT COUNT(*) FROM dual -- 1 - Lukasz Szozda
1
我明白了,谢谢你的额外解释! - Henry Yang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接