【问题标题】:Oracle SQL multiple left joins with duplicate records or "invalid identifier"具有重复记录或“无效标识符”的 Oracle SQL 多个左连接
【发布时间】:2018-01-17 11:27:43
【问题描述】:

我对 SQL 还很陌生,以前也做过一些连接,但没有这么复杂。

基本上,我要做的是将许多表连接在一起以显示报告的整体数据。主表g,是我想查看详细程度的地方。 g 与附加到它的所有表具有一对多关系。 GROUP BY 会消除这些重复项吗?

我尝试过使用SELECT DISTINCT,但我不确定这是否是最佳解决方案。

这是我当前正在运行的 SQL 的输出ORA-00904: "a"."akey": invalid identifier

SELECT 
a.afield123 ORDER_QTY,
b.bfield123 MANUF,
c.cfield123 ORDER_DATE,
d.dfield123 PATIENT_CREATE_DATE,
e.efield123 PAYOR_CLASS,
f.ffield123 ID

FROM

schema123.a12345            a,
schema123.b12345            b,
schema123.c12345            c,
schema123.d12345            d,
schema123.e12345            e,
schema123.f12345            f,

LEFT JOIN schema123.g12345  g ON     
(a.akey = b.akey AND
 c.ckey = d.ckey AND 
 e.ekey = f.ekey)

这是一些示例数据

G 表(主表) Primary Key: gfield123 Foreign Keys: akey,bkey,ckey,dkey,ekey,fkey,hkey

gfield123   gfield124   akey    bkey    ckey    dkey    ekey    fkey   hkey
1           8/1/2017    1234    2234    3234    4234    5234    6234   7234

一张桌子 Primary Key: akey Foreign Keys: gfield123, bkey

akey    afield123   gfield123   bkey        
1234    20          1           2234        
1235    40          1           2234        

B 表 Primary Key: bkey Foreign Keys: gfield123, ckey, akey

bkey    bfield123   gfield123 akey  ckey    
2234    COMPANY1    1         1234  3234    

C 表 Primary Key: ckey Foreign Keys: gfield123, bkey, dkey

ckey    cfield123   gfield123   bkey    dkey    
3234    8/5/2017    1           2234    4234     

D 表 Primary Key: dkey Foreign Keys: gfield123, ckey, ekey

dkey    dfield123       gfield123   ckey    ekey    
4234    7/1/2017        1           3234    5234    

E 表 Primary Key: ekey Foreign Keys: gfield123, fkey

ekey    efield123       gfield123   fkey
5234    MEDICARE        1           6234 

F 表 Primary Key: fkey Foreign Key: gfield123

fkey    ffield123         gfield123 
6234    ABC123            1         

H 表 Primary Key: hkey

hkey    hfield123           
7234    9999                   

预期结果

gfield123   afield123   bfield123 cfield123 efield123 ffield123 hfield123
1           60          COMPANY1  8/5/2017  MEDICARE  ABC123    9999    

编辑:SQL 简化、数据样本、预期结果

【问题讨论】:

  • "这是一大段代码。" “我们需要一个更大的调试器。”
  • 不要将 ANSI 连接与旧式 Oracle 语法混用;在您的第一个版本中,将 from 子句中所有以逗号分隔的表重写为具有合适的 on 子句的正确(内部)join 语句。这种混合可能是为什么PAY 在您期望的地方不可见,但是对于人们和优化器来说,这种混合会变得混乱和混乱。
  • 你能提供一个SCHEMANAME.BT_PAYOR PAY, 的例子吗?我不熟悉 ANSI 和旧式 Oracle 之间的区别。
  • 伙计,简化。了解How to create a Minimal, Complete, and Verifiable example。我对你的问题投了反对票,因为除了你之外别无他法。
  • @AnthonyKnisely 相信我,你不想在 cmets 中就本网站的目的进行辩论。查看 MCVE 链接,了解为什么这个问题对您来说很难获得帮助。

标签: sql oracle duplicates left-join


【解决方案1】:

如果你想要来自 G 的所有记录,并且只想要那些在 a-b-c-d-e-f 中匹配的记录,那么

除非发生聚合,否则通常不会使用分组依据。 Distinct 告诉我们您知道表连接中有重复项,并且您想从结果中消除它们。

SELECT sum(a.afield123) as ORDER_QTY
     , b.bfield123 as MANUF
     , c.cfield123 as ORDER_DATE
     , d.dfield123 as PATIENT_CREATE_DATE
     , e.efield123 as PAYOR_CLASS
     , f.ffield123 as ID
     , g.gfield123 as gkey
     , g.hfield123 as hField123
FROM schema123.g12345 g
LEFT JOIN schema123.a12345 a
  ON g.gkey = a.gkey
LEFT JOIN schema123.b12345 b
  ON a.akey = b.akey
 AND g.gkey = b.gkey
LEFT JOIN schema123.c12345 c
  ON b.bkey = c.bkey
 AND g.gkey = c.gkey
LEFT JOIN schema123.d12345 d
  ON c.ckey = d.ckey
 AND g.gkey = d.gkey
LEFT JOIN schema123.e12345 e
  ON d.dkey = e.dkey
 AND g.gkey = g.gkey
LEFT JOIN schema123.f12345 f
  ON e.ekey = f.ekey
 AND g.gkey = g.gkey
LEFT JOIN schema123.f12345 
  on g.hkey = h.hkey
GROUP BY , b.bfield123 as MANUF
     , c.cfield123 as ORDER_DATE
     , d.dfield123 as PATIENT_CREATE_DATE
     , e.efield123 as PAYOR_CLASS
     , f.ffield123 as ID
     , g.gfield123 as gkey
     , g.hfield123 as hField123

注意我们

  • 删除了 from 子句中的逗号符号,它是 89 标准。是的,这差不多是 30 年前的事了
  • 已将 g.field123 gkey 添加到 select 如果不选择任何内容,为什么要加入表格?
  • 将 g 移动到 from 中的第一个条目(您想要 G 中的所有记录,并且只希望那些在其他表链中匹配的记录吗?
  • 为每个连接添加一个左连接和一个 on 子句。
  • 我对齐了代码,以便查看我们是否在选择中缺少 ,。
  • 假设键符号有意义。
  • 假设 join g.gkey = a.akey 因为您没有说明 g 与其他表的关系。
  • 如果添加 WHERE 子句,则只能在其中添加对 g 的限制。
  • 如果您需要限制其他表中的值,请在连接本身上使用 AND,例如 and d.dfield123 >= to_date('2017-01-01','YYYY-MM-DD'),这样只有 2017 年创建的患者才会显示。

【讨论】:

  • 这非常有帮助,谢谢。在这种情况下,SELECT DISTINCT 是否会将所有ORDER_QTY 加在一起以反映该单个订单的总ORDER_QTY?至于其他键,g.gkey 是主键,将作为外键存在于所有其他表中。
  • 否...如果您需要求和,则 sum(a.afield123) 然后将非聚合字段添加到 group by 并消除不同的字段。对于那些需要提问的人,请考虑先与鸭子交谈。是的,我是认真的。
  • 现在您可能还想汇总其他字段,例如 Max(create date) 或 max(order_Date),这就是我想查看示例数据以及其他人要求 MVCE 的原因。这并不是说我们无礼,而是我们希望尽可能以最高效的方式帮助您。当您向 MVCE 提供数据和该数据的实际预期结果时;你需要做什么的画面变得更加清晰。此外,练习本身可以帮助您更好地理解问题。这会减少这个问题可能会有的来回喋喋不休。
  • 这是鸭子:blog.codinghorror.com/rubber-duck-problem-solving 并更新以说明 gkey 在所有表中。
  • Simpy 添加另一个左连接添加到选择和分组依据。除非此字段需要聚合,否则添加以选择 w/聚合并且没有分组依据(但仍需要连接)注意左连接将保留 G 记录,并且仅在存在时显示 H 记录。加入 FK/PK 关系的表,即使它是复合键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 2020-02-01
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多