sql - Union all 在左外连接内并没有获取所有 values,它只是将 values 拉到子查询之外(哪个 PRJ_elements)

我有一个关于使用 UNION ALL 和左外连接的问题。我想要实现的是获取项目总成本以及其他几个领域,但同时我想要很少的其他领域,如零件,来自其他 tables 的直接材料与 Union All 结合。它正在获取项目成本和左外连接子查询之外的所有字段,但由于某种原因,它没有获取包含在连接内的列。

SELECT COUNT(EVT_C) AS NumWO,
    PRJ_C AS Project, 
    PRJ_DESC AS ProjectDescription, 
    PRJ_S AS Status, 
    PRJ_DES AS MS, 
    PRJ_UDF03 AS SP, 
    SUM(Cost.Total) AS TotalIntLabour,
FROM R5PRJ
LEFT OUTER JOIN R5E ON EVT_PRJ = PRJ_CODE 
LEFT OUTER JOIN (
        SELECT
            BOO_COST AS Total,
            EVT_PRJ AS Project,
            CAST(BOO_SQLI AS NVARCHAR(400)) AS SystemReference,
            BOO_E AS DateEntered,
            'Part' AS RType,
            'Direct Materials' AS Type
        FROM R5BOO
        LEFT OUTER JOIN R5E ON EVT_C = BOO_E 
        WHERE EVT_PRJ IS NOT NULL
    UNION ALL
        SELECT 
            TRL_PRICE*TRL_QTY AS Total,
            EVT_PRJ AS Project,
            TRL_T+'+'+TRL_P AS SystemReference,
            TRL_D AS DateEntered,
            'Part' AS RType,
            'Direct Materials' AS Type
        FROM R5TR
        LEFT OUTER JOIN R5E ON TRL_E = EVT_C
        LEFT OUTER JOIN R5O ON OBJ_C = EVT_OBJ
        WHERE TRL_IO = 0 AND TRL_R IN ('RECV','RETN')
    UNION ALL 
        SELECT 
            TRL_PRICE*TRL_QTY AS Total,
            EVT_PRJ AS Project,
            TRL_T+'+'+TRL_P AS SystemReference,
            TRL_D AS DateEntered,
            'Part' AS RType,
            'Direct Materials' AS Type
        FROM R5TR
        LEFT OUTER JOIN R5E ON TRL_E = EVT_C
        LEFT OUTER JOIN R5O ON OBJ_C = EVT_OBJ
        WHERE TRL_E IS NOT NULL AND TRL_R = 'I' AND TRL_IO = -1
    ) AS Cost ON Cost.Project = PRJ_C
GROUP BY PRJ_C,PRJ_D,PRJ_S,PRJ_D,PRJUDF03,PRJ_ACTBUD,
    PRJ_ORIGBUD,PRJ_UDF01,PRJ_CLASS,PRJ_C

回答1

它没有获取包含在 Join 中的列。

您没有在外部查询中选择它们。

SQL 对数据块进行操作。 table 是输入 FROM 的数据块。查询的输出也是可以输入 FROM 的数据块。

Person table 有 3 列;姓名、生日、身高。

当你写:

SELECT name 
FROM person

你得到的只是名称,即使 table 还有另外两列

当你写:

SELECT name 
FROM (
  SELECT name, height 
  FROM person
)x

你不会突然得到姓名和身高。您说您只希望 Name 在最终执行的 SELECT (最上面的)中。仅仅因为您在内部查询中提到高度并不意味着它显示为外部查询的输出。内部查询的输出被馈送到外部查询中,而 out 查询不选择 Height 列..就像在 table 名称用于

SELECT name    --doesn't mention height
FROM person    --even though this has height

这只是“输入数据块”(在本例中为 Person table)和“输出数据块”(在本例中为一个输出反馈给您)

在此查询中:

SELECT name            --also doesn't mention height
FROM (
  SELECT name, height  --even though this has height
  FROM person
)x

我们有“来自 table 人的 3 列输入数据块变为 2 列宽输出”,即返回给您的“2 列输入数据块变为 1 列宽输出”

在外部查询中,您只能引用由内部/子查询选择的列,并使用您为子查询提供的别名来引用它们。任何联合集中的第一个查询定义整个联合集的列名

就像子查询在查询期间运行并临时变成 table 一样,因此:

SELECT sq.x
FROM (
  SELECT name as x
  FROM Person

  UNION ALL

  SELECT building_name
  FROM address
) sq

在这里您可以看到执行联合的子查询已别名为 sq。第一个查询采用人名并将其别名为 x。 union 的第二个查询从地址 table 中提取了一个建筑物名称,但该名称对列的名称没有影响。由于联合集中的第一个查询,该列被称为 x

因此,您最终会得到一个您称为 sq.x 的列,其中充满了人和建筑物名称的混合

在外部查询中,您不能在子查询中引用任何列或 tables 的任何名称;子查询运行并且它选择的列成为它被别名的数据块中的列。任何未选择的东西都消失了。如果您需要使用某些东西,您必须选择它:

SELECT sq.x
FROM (
  SELECT name as x, age as y
  FROM Person

  UNION ALL

  SELECT building_name, YEAR(GetUtcDate()) - building_built_year
  FROM address
) sq
WHERE 
  sq.y > 50

这将获取所有 50 岁以上的人或建筑物:人查询别名年龄为 y,外部查询使用 y。计算建筑年龄的公式没有别名;由于第一个查询,它进入 y

相似文章

随机推荐

最新文章