【问题标题】:SQL - query Order Header and Order Detail without DuplicationSQL - 查询订单标题和订单明细,不重复
【发布时间】:2015-04-16 18:11:48
【问题描述】:

尝试查询 Order Header 和 Detail 表以按月份汇总结果,但遇到数据模型限制。本质上,我想审核我们的 ETL 流程,以确保从 Detail 级别正确聚合 Header 级别的数据。 TRANS_ID 键字段代表一个订单,因此每个 TRANS_ID 明细表自然会有几行。

表 ORDER_HEADER 有(为了便于说明):

TRANS_ID
TRANS_DT (DD-MON-YY)
PROFIT

表 ORDER_DETAIL 有:

TRANS_ID
TRANS_LINE_NO
LINE_ITM_PROFIT

我要回答的问题是:在月份级别,Header 的总利润是多少,Detail 的总利润是多少?我的结果应该包含三列:“Trans_DT 月份”、“HDR 利润”和“DTL 利润”

如果我在 ORDER_HEADER.TRANS_ID = ORDER_DETAIL.TRANS_ID 和 GROUP BY "Month of ORDER_HEADER.TRANS_DT" 上进行内部连接,那么我显然会复制 Header 值。

我的数据量(在 Oracle RDBMS 中)约为 150MM Header 记录和超过 600MM Detail 记录,因此最好的解决方案是在加入 Header 之前将整个 Detail 表加到“TRANS_ID”级别。

【问题讨论】:

    标签: sql oracle data-modeling


    【解决方案1】:

    对子查询中的聚合执行此操作:

    select oh.yyyymm, oh.hdr_profit, od.dtl_profit
    from (select to_char(trans_dt, 'YYYY-MM') as yyyymm, sum(profit) as hdr_profit 
          from order_header
          group by to_char(trans_dt, 'YYYY-MM')
         ) oh join
         (select to_char(oh.trans_dt, 'YYYY-MM') as yyyymm,
                 sum(od.line_itm_profit) as dtl_profit 
          from order_header oh join
               order_detail od
               on oh.trans_id = od.trans_id
          group by to_char(oh.trans_dt, 'YYYY-MM')
         ) od
         on oh.yyyymm = od.yyyymm;
    

    【讨论】:

    • 在我看来,如果 order_header 在不同的地方有两个不同的别名会更好;)
    【解决方案2】:

    对 Gordon 的解决方案进行了一些小的更正。 注意 - 这里只有 ORDER_HEADER 表中的月份。

    select oh.TRANS_MONTH "Month of TRANS_DT", oh.PROFIT "HDR Profit", od.PROFIT "DTL Profit"
    from
    (
    select TO_CHAR(TRANS_DT, 'YYYY-MM') TRANS_MONTH , SUM(LINE_ITM_PROFIT) PROFIT
    from ORDER_HEADER
    group by TO_CHAR(TRANS_DT, 'YYYY-MM')
    ) oh
    left join 
    (
    select TO_CHAR(TRANS_DT, 'YYYY-MM') TRANS_MONTH, SUM(LINE_ITM_PROFIT) PROFIT
    from ORDER_DETAIL od
    where TRANS_ID in (select TRANS_ID from ORDER_HEADER)
    group by TO_CHAR(TRANS_DT, 'YYYY-MM')
    ) od
    on oh.TRANS_MONTH = od.TRANS_MONTH
    

    【讨论】:

    • “od”查询不会很贵吗?此外,我假设所有子 Detail 记录都具有有效的 Header 父记录,因此可能会呈现 TRANS_ID in (select TRANS_ID from ORDER_HEADER)moot
    • 您写了“最好的解决方案是在加入 Header 之前不会将整个 Detail 表加到“TRANS_ID”级别”,所以我猜 ORDER_DETAIL 表中有没有对应的记录在 ORDER_HEADER 中。
    猜你喜欢
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2017-01-06
    • 2013-02-05
    • 1970-01-01
    • 2012-04-30
    • 2017-04-23
    相关资源
    最近更新 更多