【问题标题】:SQL Using Order By in Union StatementSQL 在 Union 语句中使用 Order By
【发布时间】:2018-05-26 15:57:23
【问题描述】:

请看下面我正在努力的代码:

select * 
from AAA_PROD_XEUSS.P_E_LVR_CQT CQT 
left join AAA_PROD_XEUSS.P_F_OPERATION OPER
on CQT.OPERATION = OPER.OPERATION
union
select * 
from BBB_PROD_XEUSS.P_E_LVR_CQT CQT
left join BBB_PROD_XEUSS.P_F_OPERATION OPER
on CQT.OPERATION = OPER.OPERATION
where CQT.PROCESS = '1111'
Order by OPERATION

我收到以下错误: 错误 [42877] [IBM][DB2/LINUXX8664] SQL0197N ORDER BY 子句中不允许有限定的列名。 任何给出错误的建议解决方案

谢谢

【问题讨论】:

  • 谢谢。错误:错误 [42702] [IBM][DB2/LINUXX8664] SQL0203N 对列“OPERATION”的引用不明确

标签: sql db2 sql-order-by union


【解决方案1】:

您可以使用order by,但您需要明确列出列。无论如何,这是一个很好的做法:

select cqt.*, oper.?, oper.?, . . .
from AAA_PROD_XEUSS.P_E_LVR_CQT CQT left join
     AAA_PROD_XEUSS.P_F_OPERATION OPER
    on CQT.OPERATION = OPER.OPERATION
union
select cqt.*, oper.?, oper.?, . . .
from BBB_PROD_XEUSS.P_E_LVR_CQT CQT left join
     BBB_PROD_XEUSS.P_F_OPERATION OPER
     on CQT.OPERATION = OPER.OPERATION
where CQT.PROCESS = '1111'
Order by OPERATION;

OPERATION 列应该来自CQT 表。 ?s 是 OPER 中其他列的占位符。这假定两个CQT 表具有相同的列,并且以相同的顺序定义了相同的类型。更好的做法是列出所有列。

【讨论】:

    【解决方案2】:

    如果您使用的是 Db2 11.1,则可以使用 JOIN USING 语法来避免在结果集 https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0059207.html 中有两个连接列的副本

    例如用这些表

    create table AAA_PROD_XEUSS.P_E_LVR_CQT   (i int, OPERATION int, PROCESS char(4)););
    create table AAA_PROD_XEUSS.P_F_OPERATION (b int, OPERATION int);
    create table BBB_PROD_XEUSS.P_E_LVR_CQT   (c int, OPERATION int, PROCESS char(4));
    create table BBB_PROD_XEUSS.P_F_OPERATION (b int, OPERATION int);
    

    这个选择

    select * 
    from AAA_PROD_XEUSS.P_E_LVR_CQT CQT 
    left join AAA_PROD_XEUSS.P_F_OPERATION OPER
    USING ( OPERATION )
    union
    select * 
    from BBB_PROD_XEUSS.P_E_LVR_CQT CQT
    left join BBB_PROD_XEUSS.P_F_OPERATION OPER
    USING ( OPERATION )
    where CQT.PROCESS = '1111'
    Order by OPERATION
    

    将只返回一个名为 OPERATION 的列

    OPERATION I PROCESS B
    --------- - ------- -
    
    0 record(s) selected.
    

    附:您可能更喜欢使用 UNION ALL 而不仅仅是 UNION 以避免 Db2 必须对所有行进行排序以删除重复项

    【讨论】:

    • USING 只连接JOIN 子句左右两个表。因此,我认为加入具有相同列名的其他表没有任何“风险”。您是否正在考虑连接所有同名列的“自然连接”? (这在 Db2 中不受支持)。仅供参考,手册说“此子句连接指定列上的表。每一列都存在于要连接的 both 表中。”
    • 哇。我不确定我从哪里得到USINGNATURAL 会收集所有可能的列;看起来所有主要的 RDBMS 都只使用左/右表。撤回。
    【解决方案3】:

    外面取order by子句,取内部select列表中所有列的别名。

    cqt.operationoper.operation 中的一个可能是首选,因为它们被匹配为相等):

    Select * 
    from
        (select cqt.col1, cqt.col2, oper.* 
         -- where "operation" column is exempted from cqt list, 
         --  since the table aliased as oper already has "operation" column.
         from AAA_PROD_XEUSS.P_E_LVR_CQT CQT 
         left join AAA_PROD_XEUSS.P_F_OPERATION OPER on CQT.OPERATION = OPER.OPERATION
         union
         select cqt.col1, cqt.col2, oper.*
         from BBB_PROD_XEUSS.P_E_LVR_CQT CQT
         left join BBB_PROD_XEUSS.P_F_OPERATION OPER on CQT.OPERATION = OPER.OPERATION
         where CQT.PROCESS = '1111'
    ) 
    Order by OPERATION
    

    【讨论】:

    • 谢谢。如果列数很大,我该怎么办?给他们都起别名?
    • @Felix 不客气。其中哪个列大可能会标有星号,而对于另一个表,我们需要为它们起别名(cqt.col1,cqt.col2,oper.* 没有操作列对于别名为 CQT 的表,别名为 OPER 的表已经有操作列)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 2010-09-17
    • 2014-09-26
    • 2010-10-04
    • 2011-04-01
    相关资源
    最近更新 更多