【问题标题】:Error 'missing from-clause entry' in Query with 'union' and 'order by'使用 'union' 和 'order by' 的查询中出现错误 'missing from-clause entry'
【发布时间】:2014-06-08 14:28:30
【问题描述】:

我有一个包含 3 个联合和一个 order by 子句的查询。

因此,如果 s1、s2、s3 和 s4 是包含选择查询的字符串变量,而 oc 是包含 order by 子句的字符串变量,则完整查询是:

s1 & " union " & s2 & " union " & s3 & " union " & s4 & oc

每个选择的格式完全相同,只是参数不同,每个选择都包含多个连接。

此查询失败并出现错误

运行时错误:'-2147467259 (80004005)':

表“eventTbl”缺少从子句条目;出错时 执行查询

但是,以下所有变体都不会导致错误

s1 & " union " & s2 & " union " & s3 & " union " & s4

s1 & oc

s2 & oc

s3 & oc

s4 & oc

导致错误的查询在 .mdb 格式的同一数据库上运行正常。

postgresql 服务器是 postgres 9.0 该程序是带有 ADO 2.6 的 vb6,连接字符串是

提供者=MSDASQL;驱动程序={PostgreSQL ANSI};SERVER=localhost;DATABASE=dbname;UID=postgres;PWD=password;CONNSETTINGS=SET 日期样式到 'DMY'%3b;BOOLSASCHAR=0;TEXTASLONGVARCHAR=1;TrueIsMinus1=1;

编辑 每个单独选择的结构如下:

 select Charges.CHARGESCALENAMEF1, MATERIALST12.MATERIALNAMEF1
   , workspecificationst11.*
   , clientdetail.clientidf9
   , eventTbl.*
 from Charges
 right join (MATERIALST12 
            right join  (workspecificationst11 
                         right join (clientdetail
                                      right join  eventTbl
                                      on clientdetail.clientidf9 = eventTbl.clientidf2
                                    ) on workspecificationst11.serialnumf5 = eventTbl.workf5
                         ) ON MATERIALST12.SERIALNUMF3 = eventTbl.MATERIALF8
           ) ON Charges.SERIALNUMF2 = eventTbl.CHARGESCALEF7
 where eventTbl.clientidf2 = 15249
 and  eventTbl.workf5 = 40
 and  eventTbl.workstatusf14 = 2
 and eventTbl.section = 1
 and workspecificationst11.showinaccountsf9 = true
  ;

【问题讨论】:

  • 什么是s1 &?请贴出真实代码。
  • @wildplasser 我已经编辑了问题以显示选择的构成
  • '&'是vb6中的字符串连接运算符
  • 您的查询中没有表“tablename”,一定是其他查询失败。
  • @FrankHeikens,对不起,我现在才解决这个问题。抱歉,我想以一种抽象的方式发布了这个问题。是的,查询 eventbl 中的表缺少 from 子句,尽管我看不到如何

标签: postgresql


【解决方案1】:

去掉所有括号:

select Charges.CHARGESCALENAMEF1, MATERIALST12.MATERIALNAMEF1
   , workspecificationst11.*
   , clientdetail.clientidf9
   , eventTbl.*
 from Charges
 right join eventTbl ON Charges.SERIALNUMF2 = eventTbl.CHARGESCALEF7
 right join clientdetail on clientdetail.clientidf9 = eventTbl.clientidf2
 right join MATERIALST12 ON MATERIALST12.SERIALNUMF3 = eventTbl.MATERIALF8
 right join workspecificationst11 on workspecificationst11.serialnumf5 = eventTbl.workf5
 where eventTbl.clientidf2 = 15249
 and eventTbl.workf5 = 40
 and eventTbl.workstatusf14 = 2
 and eventTbl.section = 1
 and workspecificationst11.showinaccountsf9 = true

【讨论】:

  • 非常感谢。不幸的是,删除括号并没有改变错误,同样的错误出现了:(我只是用postgresql弄湿了我的脚趾,所以我会查找你关于使用别名等的其他建议。我想我希望我们能够如果将数据库移动到 postgresql,则或多或少地重用我们为 mdb 格式的 db 工作的毛茸茸的旧 sql。这有点令人沮丧,因为其他查询的性能很棒!
  • 在创建所有 UNION 之前,首先测试单独的组件。 (顺便说一句:所有这些 RIGHT JOINS 看起来非常很奇怪......)
  • “它们是非常古老而古老的查询......”它们在语法上也是错误的。在将它们连接在一起之前先修复它们。
  • 我不知道这是否会引起任何人的兴趣。 “order by”子句是“order by eventbl.datef1, eventtbl.eventidf15”。将其更改为简单的 'order by datef1, eventidf15' 解决了问题。
  • @Davos 谢谢,很高兴它以某种方式有所帮助
【解决方案2】:

如果我理解正确,完整的查询最终会类似于以下内容,尽管我已将其简化为两个 SELECT 语句,它们之间有一个 UNION,最后是一个 ORDER BY 子句。根据上面的 cmets,您发现:

当查询包含 UNION 时,ORDER BY 子句中的 table alias(在您的情况下为 eventTbl)不起作用。

我怀疑这是因为每个选择查询都有一个 eventTbl 的本地表别名,但总的来说,该查询在整个查询范围内没有表别名。此外,ORDER BY 适用于整个结果集,而不适用于单个 SELECT 语句。

SELECT Charges.CHARGESCALENAMEF1, MATERIALST12.MATERIALNAMEF1
   , workspecificationst11.*
   , clientdetail.clientidf9
   , eventTbl.*
 from Charges
 right join (MATERIALST12 
            right join  (workspecificationst11 
                         right join (clientdetail
                                      right join  eventTbl
                                      on clientdetail.clientidf9 = eventTbl.clientidf2
                                    ) on workspecificationst11.serialnumf5 = eventTbl.workf5
                         ) ON MATERIALST12.SERIALNUMF3 = eventTbl.MATERIALF8
           ) ON Charges.SERIALNUMF2 = eventTbl.CHARGESCALEF7
 where eventTbl.clientidf2 = 15249
 and  eventTbl.workf5 = 40
 and  eventTbl.workstatusf14 = 2
 and eventTbl.section = 1
 and workspecificationst11.showinaccountsf9 = true

UNION

SELECT Charges.CHARGESCALENAMEF1, MATERIALST12.MATERIALNAMEF1
   , workspecificationst11.*
   , clientdetail.clientidf9
   , eventTbl.*
 from Charges
 right join (MATERIALST12 
            right join  (workspecificationst11 
                         right join (clientdetail
                                      right join  eventTbl
                                      on clientdetail.clientidf9 = eventTbl.clientidf2
                                    ) on workspecificationst11.serialnumf5 = eventTbl.workf5
                         ) ON MATERIALST12.SERIALNUMF3 = eventTbl.MATERIALF8
           ) ON Charges.SERIALNUMF2 = eventTbl.CHARGESCALEF7
 where eventTbl.clientidf2 = 15249
 and  eventTbl.workf5 = 40
 and  eventTbl.workstatusf14 = 2
 and eventTbl.section = 1
 and workspecificationst11.showinaccountsf9 = true
ORDER BY eventbl.datef1, eventtbl.eventidf15;

ORDER BY 中删除表别名有效,因为作为单个查询,上面返回一个datef1 列和一个eventiff15 列,但没有在整个结果集中定义表别名。

解决方案
ORDER BY 子句中删除表别名:

ORDER BY datef1, eventidf15;

如果您执行以下操作,我想您可以使表别名起作用:

SELECT * FROM
( Original full query goes here without the order by) AS eventTbl
ORDER BY eventbl.datef1, eventtbl.eventidf15;

但这有点过分了。

【讨论】:

    【解决方案3】:

    建议重构:

    WITH parms as (
       SELECT 15249 as clntid, 40 as wrkf, 2 as wkstat, sect = 1
       UNION ALL
       SELECT 14349 as clntid, 37 as wrkf, 23 as wkstat, sect = 5
       UNION ALL
       SELECT 16822 as clntid, 106 as wrkf, 55 as wkstat, sect = 2
       UNION ALL
       SELECT 24253 as clntid, 9 as wrkf, 43 as wkstat, sect = 9
    )
    from 
        CHARGES
           right join 
        eventTbl 
              ON Charges.SERIALNUMF2 = eventTbl.CHARGESCALEF7
           right join 
        clientdetail 
              on clientdetail.clientidf9 = eventTbl.clientidf2
           right join 
        MATERIALST12 
              ON MATERIALST12.SERIALNUMF3 = eventTbl.MATERIALF8
           right join 
        workspecificationst11 
              on workspecificationst11.serialnumf5 = eventTbl.workf5
           RIGHT JOIN 
        PARMS 
              ON (
                  eventTbl.clientidf2 = PARMS.clntid
                  and eventTbl.workf5 = PARMS.wrkf
                  and eventTbl.workstatusf14 = PARMS.wkstat
                  and eventTbl.section = PARMS.sect
              )
    WHERE
       workspecificationst11.showinaccountsf9 = true
    

    【讨论】:

    • 谢谢,现在才看到这个。是的,原来的查询很糟糕
    猜你喜欢
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    相关资源
    最近更新 更多