【问题标题】:View Query on parent and child table查看父子表查询
【发布时间】:2013-01-24 07:17:58
【问题描述】:

我使用的是 Oracle 11G,我有下面的表结构

STATE_DEF 表是父表

TAX_DEF_ID  EFFECTIVE_DATE  REP_TYPE
1           9-Jan-12        R
2           15-Jan-12       W

和子表'TAX_DETAIL'如下

TAX_DETAIL_ID   TAX_TYPE    DISTRIBUTION_TYPE   WH_RATE   TAX_DEF_ID
1               I           S                   0.1       1
2               I           P                   0.12      1
3               D           S                   0.2       1
4               D           P                   0.22      1
5               I           S                   0.3       2
6               I           P                   0.31      2
7               D           S                   0.4       2
8               D           P                   0.41      2

我想创建一个视图,它会给出如下所示的输出

TAX_DEF_ID  EFFECTIVE_DATE  I_S_WH_RATE    I_P_WH_RATE  D_S_WH_RATE   D_P_WH_RATE
1           9-Jan-12        0.1            0.12         0.2           0.22
2           15-Jan-12       0.3            0.31         0.4           0.41

我尝试过 LISTAGG 函数,但它会给我一个带有连接列的列。我正在寻找视图定义,它将在不同的列中为我提供生效日期的费率。

这几天我一直在尝试获得这个输出。我会感谢任何帮助以实现上述结果。

【问题讨论】:

    标签: sql view oracle10g oracle11g


    【解决方案1】:

    试试这个:

    SELECT
        SD.TAX_DEF_ID,
        SD.EFFECTIVE_DATE,
        SUM(CASE WHEN TAX_TYPE = 'I' AND DISTRIBUTION_TYPE = 'S' THEN WH_RATE ELSE 0 END) I_S_WH_RATE,
        SUM(CASE WHEN TAX_TYPE = 'I' AND DISTRIBUTION_TYPE = 'P' THEN WH_RATE ELSE 0 END) I_P_WH_RATE,
        SUM(CASE WHEN TAX_TYPE = 'D' AND DISTRIBUTION_TYPE = 'S' THEN WH_RATE ELSE 0 END) D_S_WH_RATE,
        SUM(CASE WHEN TAX_TYPE = 'D' AND DISTRIBUTION_TYPE = 'P' THEN WH_RATE ELSE 0 END) D_P_WH_RATE
    FROM STATE_DEF SD
        LEFT JOIN TAX_DETAIL TD
            ON SD.TAX_DEF_ID = TD.TAX_DEF_ID
    GROUP BY SD.TAX_DEF_ID, SD.EFFECTIVE_DATE
    

    【讨论】:

    • 这是我的答案的大写 :)))
    • 不,我的答案不是你的副本。仔细观察,如果没有为 TAX_DEF 找到 TAX_DETAIL 或没有为适当的列找到 TAX_TYPE、DISTRIBUTION_TYPE 组合,您将得到 NULL 而不是 0。
    • 我没说是副本。我们同时回答。但答案看起来非常相似。
    • 感谢您的回复。尽管还有其他正确的答案,但我接受它只是因为它会给我我正在寻找的输出。当没有孩子时,我需要 I_S_WH_RATE 和其他列为零。这很棒。
    【解决方案2】:

    请使用PIVOT查看结果

    select * From(
      select 
        a.TAX_DEF_ID, 
        a.EFFECTIVE_DATE, 
        TAX_TYPE||DISTRIBUTION_TYPE AS TYP, 
        WH_RATE 
      From STATE_DEF a INNER JOIN TAX_DETAIL b ON a.TAX_DEF_ID=b.TAX_DEF_ID
    )x 
    PIVOT
    (MAX(WH_RATE) as WH_RATE for (TYP) IN ('IS' AS I_S, 'IP' as I_P, 'DS' as D_S, 'DP' as D_P)); 
    

    【讨论】:

    • 感谢您的回复。这个答案也给了我正确的结果。我希望我能接受更多的答案:)
    • 没关系...很高兴听到我的查询提供了所需的输出:)
    【解决方案3】:
    select 
      tax_def_id,
      effective_date,
      sum(case when d.tax_type='I' and d.distribution_type='S' then wh_rate end) as I_S_WH_RATE
      --and so on...
    from state_def t
    join tax_detail d on (t.tax_def_id = d.tax_def_id)
    group by   
       tax_def_id, 
       effective_date
    

    【讨论】:

    • 不,我的答案不是你的副本。 仔细观察,如果没有TAX_DETAIL found for TAX_DEF` 或没有TAX_TYPEDISTRIBUTION_TYPE 组合,您将得到NULL 而不是0
    • 不过,总和是正确的。这是我们的答案之间的差异,而不是错误。很多时候,空值比零好。价值的不存在表示与零价值不同的东西。
    【解决方案4】:

    在 11g 中,您可以对此进行调整:

    with data as (select s.TAX_DEF_ID, s.EFFECTIVE_DATE, d.TAX_TYPE, d.DISTRIBUTION_TYPE, d.WH_RATE
                    from state_def s
                         inner join tax_detail d
                                 on s.tax_def_id = d.tax_def_id)
    select *
      from data
           pivot(max(wh_rate)
                 for (TAX_TYPE, DISTRIBUTION_TYPE)
                 in (('I', 'S') as I_S_WH_RATE,
                     ('I', 'P') as I_P_WH_RATE,
                     ('D', 'S') as D_S_WH_RATE,
                     ('D', 'P') as D_P_WH_RATE
                    )
                );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多