【问题标题】:LEFT JOIN & SUM GROUP BYLEFT JOIN 和 SUM GROUP BY
【发布时间】:2021-01-30 19:56:54
【问题描述】:

编辑: 结果应该是这样的: desired result

我有这个问题:

SELECT DISTINCT mitarbeiter.mitarbnr, mitarbeiter.login, mitarbeiter.name1, mitarbeiter.name2
FROM vertragspos
left join vertrag_ek_vk_zuord ON vertragspos.id = vertrag_ek_vk_zuord.ek_vertragspos_id
left join mitarbeiter ON vertrag_ek_vk_zuord.anlage_mitarbnr = mitarbeiter.mitarbnr
left join vertragskopf ON vertragskopf.id = vertragspos.vertrag_id
left join
(
   SELECT wkurse.*, fremdwaehrung.wsymbol
   FROM wkurse
   INNER join
   (
    SELECT lfdnr, Max(tag) AS maxTag
    FROM wkurse
    WHERE tag < SYSDATE
    GROUP BY lfdnr
   ) t1
    ON wkurse.lfdnr = t1.lfdnr AND wkurse.Tag = t1.maxTag
    INNER JOIN fremdwaehrung ON wkurse.lfdnr = fremdwaehrung.lfdnr
) wkurse ON vertragskopf.blfdwaehrung = wkurse.lfdnr
left join
(
    SELECT vertrag_ID, Sum (preis) preis, Sum (menge) menge, Sum (preis * menge / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
    FROM vertragspos
    GROUP BY vertrag_ID
) s ON  vertragskopf.id = s.vertrag_id

但我总是在第 21 行 Pos 145 上遇到错误:

ORA-00904 WKURSE.KURS invalid identifier

WKURSE 表应该已经在上面加入了,但是为什么我仍然得到错误? 我怎样才能加入所有这些表? 我需要加入所有这些表: Mitarbeiter、Vertragspos、vertrag_ek_vk_zuord、wkurse、fremdwaehrung、vertragskopf。

什么是正确的语法?我正在使用 SQL 工具 1,8 b38 谢谢。

【问题讨论】:

  • 我认为您不能在子查询中访问 WKURSE.kurs,因为 WKURSE 本身就是一个子查询。
  • 这张桌子是什么? “vertragskopf”你在加入条件中使用它,但没有提到她......请在你的加入条款中添加它......
  • @ellawidya 你明白我的评论吗?
  • @VBoka,是的,我愿意。我已更改并加入表 vertragskopf 但它仍然给出相同的错误结果。
  • 很高兴您找到了解决问题的方法。但是,实际的答案/解决方案应该被编辑到您的问题中。一般来说,您应该edit 问题来澄清它,但不要在其中包含答案。您应该使用用于解决问题的代码/解决方案创建自己的答案,然后接受它(系统可能需要 48 小时延迟才能这样做)。当你自己解决了问题时,answering your own question is encouraged

标签: sql oracle join group-by sum


【解决方案1】:

因为LEFT JOIN 是在整个数据集上执行的,而不是以逐行方式执行的。所以在子查询的执行上下文中没有wkurse.kurs 可用。由于您加入了这些表,因此您可以将计算放在最顶层的 select 语句中。

编辑: 编辑声明后,vertragskopf.zahlintervall 的来源就很清楚了。但是我不知道你打算在哪里使用计算出的vertragswert(现在查询中没有它),所以我把它放在了结果中。由于我不是 SQL 解析器并且不知道您的表,所以我无法检查代码,但现在可以解析计算(所有值都在计算上下文中可用)。

SELECT DISTINCT mitarbeiter.mitarbnr, mitarbeiter.login, mitarbeiter.name1, mitarbeiter.name2, s.amount / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
  left join vertrag_ek_vk_zuord ON vertragspos.id = vertrag_ek_vk_zuord.ek_vertragspos_id
  left join mitarbeiter ON vertrag_ek_vk_zuord.anlage_mitarbnr = mitarbeiter.mitarbnr
  left join vertragskopf ON vertragskopf.id = vertragspos.vertrag_id
  left join (
   SELECT wkurse.*, fremdwaehrung.wsymbol
   FROM wkurse
   INNER join (
    SELECT lfdnr, Max(tag) AS maxTag
    FROM wkurse
    WHERE tag < SYSDATE
    GROUP BY lfdnr
   ) t1
    ON wkurse.lfdnr = t1.lfdnr AND wkurse.Tag = t1.maxTag
   INNER JOIN fremdwaehrung ON wkurse.lfdnr = fremdwaehrung.lfdnr
  ) wkurse ON vertragskopf.blfdwaehrung = wkurse.lfdnr
  left join (
    SELECT vertrag_ID, Sum (preis) preis, Sum (menge) menge, Sum (preis * menge) as amount
    FROM vertragspos
    GROUP BY vertrag_ID
  ) s ON  vertragskopf.id = s.vertrag_id

使用 WITH 子句重写代码比 select from select 更清晰。

在oracle中获取前一天的汇率也很简单

select wkurse.lfdnr
  , max(wkurse.kurs) keep (dense_rank first order by wkurse.tag desc) as rate
from wkurse
where tag < sysdate
  group by wkurse.lfdnr

【讨论】:

  • 你能写出语法吗?如果你看一下 WKURSE,我还需要将 join 与 sum 结合起来。
  • @ella widya 不,我不能。由于您没有在任何地方使用计算出的“vertragswert”,我无法理解您为什么要进行该计算。
  • Preis 以不同的货币表示,如欧元、美国、加元等。这就是为什么我必须用 kurs 计算它才能将所有 Preis 转换为 EUR。所以 vertragsert 是总价,单位是欧元。
  • 感谢您的帮助!由于您的语法,我可以得到我想要的结果。
  • @ellawidya 从您的代码中我看到货币在标题表中,因此 Sum (preis * menge) 将返回分组到 contract_id 的行项目的所需结果。然后您应该将其转换为您的货币并再次求和:sum(s.amount / Decode ...)。
【解决方案2】:

一种选择是横向连接:

left join lateral
(SELECT vertrag_ID, Sum(preis) as preis, Sum(menge) as menge,
        Sum (preis * menge / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
 FROM vertragspos
 GROUP BY vertrag_ID
) s
ON  vertragskopf.id = s.vertrag_id

【讨论】:

    猜你喜欢
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    相关资源
    最近更新 更多