0

PL/SQL 不是我的强项。我很擅长 SQL,但如果可能的话,我有一个挑战,我真的可以使用你的帮助。如果有帮助,我正在使用 SQL Developer。

我有一个表,它是来自其他两个表的连接,但可以说,它具有以下适用列:

FTE_NAME              (VARCHAR2)
PRIMARY_BILLALBE_ROLE (VARCHAR2)
INVOICABLE_ALLOCATION (NUMBER)
CONTRACTED_FTE        (NUMBER)
FTE_COUNTRY           (VARCHAR2)
BILLING_START_DATE    (DATE)
BILLING_END_DATE      (DATE)

这是我正在尝试做的一个示例:
我实际上已经使用 VBA 和 excel 完成了这项工作,并且效果很好,但是现在数据在 Oracle 服务器上,并且是时候进行更新了。

示例行:

|   FTE_NAME | PRIMARY_BILLABLE_ROLE | INVOICEABLE_ALLOCATION | CONTRACTED_FTE | FTE_COUNTRY | BILLING_START_DATE | BILLING_END_DATE |
|------------|-----------------------|------------------------|----------------|-------------|--------------------|------------------|
| John Smith |     Associate Manager |                      1 |              1 |         USA |   January, 01 2013 |     May, 01 2013 |
| John Smith |               Manager |                      1 |              1 |         USA |       May, 02 2013 |           (null) |

我需要做的是,PL/SQL 代码将构建一个月度表并逐行包含或排除该月中的行,因此从01-JAN-201305-MAY-2013,月度表现在可能看起来像这样,前面有一个 MONTH COLUMN:

|           MONTHLY |   FTE_NAME | PRIMARY_BILLABLE_ROLE | INVOICEABLE_ALLOCATION | CONTRACTED_FTE | FTE_COUNTRY | BILLING_START_DATE | BILLING_END_DATE |
|-------------------|------------|-----------------------|------------------------|----------------|-------------|--------------------|------------------|
|  January, 01 2013 | John Smith |     Associate Manager |                      1 |              1 |         USA |   January, 01 2013 |    May, 01 2013  |
| February, 01 2013 | John Smith |     Associate Manager |                      1 |              1 |         USA |   January, 01 2013 |    May, 01 2013  |
|    March, 01 2013 | John Smith |     Associate Manager |                      1 |              1 |         USA |   January, 01 2013 |    May, 01 2013  |
|    April, 01 2013 | John Smith |     Associate Manager |                      1 |              1 |         USA |   January, 01 2013 |    May, 01 2013  |
|      May, 01 2013 | John Smith |     Associate Manager |                      1 |              1 |         USA |   January, 01 2013 |    May, 01 2013  |
|      May, 01 2013 | John Smith |               Manager |                      1 |              1 |         USA |       May, 02 2013 |           (null) |

的行都MAY将包含01-MAY-2013在行中,因为那几天该经理仍然担任副经理。我使用开始日期和结束日期来计算天数。

我需要帮助的主要部分是如何MONTHLY使用当月的第一天使用列构建表格。每天将有 1000 条线路和每座建筑物。我会让这段代码在一个视图中运行,该视图将提供报告和仪表板。

我非常感谢您能提供的任何帮助。

大卫

4

1 回答 1

0

您可以像以下示例查询一样从头开始填充所需的日期:

with report_params as (
  -- just to introduce variables 
  select 
    2013 year_value,
    4    start_month,
    6    end_month
  from  dual
),
report_months as (
  -- list of first dates of all required months 
  select 
    add_months( -- add months to
        trunc( -- January, 1st of year from parameters
          to_date(
            (select year_value from report_params), 
            'yyyy'
          ),
          'yyyy'
        ), 
        (select start_month from report_params) + level - 2
    )
  from 
    dual 
  connect by 
    -- select number of rows (levels) from start_month to end_month
    level <= (select end_month - start_month + 1 from report_params)
)
select * from report_months;

另一种可能性是分析一个表并在最小值和最大值之间生成音调:

with bound_months as (
  select 
    min(trunc(billing_start_date,'mm')) as first_month,
    max(trunc(billing_start_date,'mm')) as last_month
  from 
    applicable_columns
),
report_months as (
  select 
    add_months(
      (select first_month from bound_months),
      level - 1
    )
      as first_date
  from 
    dual 
  connect by 
    -- select number of rows (levels) from start_month to end_month
    level <= (select months_between(last_month,first_month)+1 from bound_months)

)
select * from report_months;

之后,您可以将月份列表加入到具有适用列的数据表/视图中:

with bound_months as (
  select 
    min(trunc(billing_start_date,'mm')) as first_month,
    max(trunc(billing_start_date,'mm')) as last_month
  from 
    applicable_columns
),
report_months as (
  select 
    add_months(
      (select first_month from bound_months),
      level - 1
    )
      as first_date
  from 
    dual 
  connect by 
    -- select number of rows (levels) from start_month to end_month
    level <= (select months_between(last_month,first_month)+1 from bound_months)

)
select
  months.first_date, 
  data.*
from 
 report_months      months,
 applicable_columns data
where 
 data.billing_start_date < add_months(months.first_date,1) 
 and
 nvl(data.billing_end_date, months.first_date) >= months.first_date
order by
  first_date, fte_name, primary_billable_role

SQLFiddle test

于 2013-09-25T23:12:25.920 回答