【问题标题】:Oracle Need to return set number of rows even when no data found即使没有找到数据,Oracle 也需要返回设置的行数
【发布时间】:2018-04-09 11:10:55
【问题描述】:

目前我有一个 oracle 查询,它查询一些数据并根据结果将它们分组到“桶”中。无论是否找到数据,这些存储桶的数量都应该是静态的。

{ "Within 5 days", "6-10 days", "11-15 days", "15-20 days", "21-25 days", "26-30 days", "> 30 days" }

为了处理这种情况,我使用 LINQ 查询和我的“桶”名称的字符串数组,并将它们映射回查询结果。如果没有找到记录,我只是创建一个新对象并将所有值设置为 0,并使用适当的存储桶标题名称(即“5 天内”)。

我想做的就是在没有任何 C# 代码的情况下处理这个问题,并让 oracle 查询返回带有硬编码标题的空行。我的限制是我不是 Oracle 专家,我也不想影响性能,所以我一直在努力寻找处理这种情况的正确和最佳方法。

如果我修改以下查询,是否有办法严格完成此操作,即使没有符合条件的数据,也始终返回 case 语句值?我知道我可以做一个联合,但我只在单行上看到了这个例子,而不需要我返回的那么多。下面的查询是我正在运行的查询的简化版本。还会返回 5 个额外的列来汇总财务数据。

   Select lag_time, NUM_DAYS
      FROM
         (SELECT  
            CLM.reported_date - CLM.loss_date as NUM_DAYS
          , CASE WHEN NVL(CLM.reported_date - CLM.loss_date,0) <= 5 THEN 'Within 5 days'
                 WHEN NVL(CLM.reported_date - CLM.loss_date,0) between 6 and 10 THEN '6-10 days'
                 WHEN CLM.reported_date - CLM.loss_date between 11 and 15 THEN '11-15 days'
                 WHEN CLM.reported_date - CLM.loss_date between 16 and 20 THEN '16-20 days'
                 WHEN CLM.reported_date - CLM.loss_date between 21 and 25 THEN '21-25 days'
                 WHEN CLM.reported_date - CLM.loss_date between 26 and 30 THEN '26-30 days'
                 WHEN CLM.reported_date - CLM.loss_date > 30 THEN 'greater than 30 days'
            END  Lag_Time                                
          FROM claim_table CLM   
          INNER JOIN policy_table IRP ON IRP.KEY = CLM.KEY                                
             WHERE IRP.POLICY_NUMBER in  ('12345678'))              
             group by lag_time
             order by lag_time

【问题讨论】:

    标签: c# sql oracle


    【解决方案1】:

    您可以使用 PIVOT 命令:

    create table xxjk as
      select 'Within 5 Days' bucket, 5 n from dual union all
      select '6 - 10 Days' bucket, 7 n from dual;
    
    select *
      from xxjk
     pivot (sum(n) for bucket in ('Within 5 Days' within_5_days,'6 - 10 Days' six_to_ten_days));
    

    当然可以推断出您自己的数据。

    【讨论】:

      【解决方案2】:

      使用LEFT OUTER JOINPIVOT 将存储桶聚合到列:

      SELECT *
      FROM   (
        SELECT POLICY_NUMBER,
               CASE
                 WHEN CLM.reported_date IS NULL OR CLM.loss_date IS NULL THEN 'No claim'
                 WHEN CLM.reported_date - CLM.loss_date <=  5            THEN 'Within 5 days'
                 WHEN CLM.reported_date - CLM.loss_date <= 10            THEN '6-10 days'
                 WHEN CLM.reported_date - CLM.loss_date <= 15            THEN '11-15 days'
                 WHEN CLM.reported_date - CLM.loss_date <= 20            THEN '16-20 days'
                 WHEN CLM.reported_date - CLM.loss_date <= 25            THEN '21-25 days'
                 WHEN CLM.reported_date - CLM.loss_date <= 30            THEN '26-30 days'
                                                                         ELSE '31 or more days'
               END  Lag_Time                                
        FROM   policy_table IRP
               LEFT OUTER JOIN claim_table CLM   
               ON IRP.KEY = CLM.KEY                                
        WHERE  IRP.POLICY_NUMBER in  ('12345678')
      ) t
      PIVOT(
        COUNT( 1 )
        FOR lag_time IN (
          'No claim'        AS "no_claims",
          'Within 5 days'   AS "within_5_days",
          '6-10 days'       AS  "6_to_10_days",
          '11-15 days'      AS "11_to_15_days",
          '16-20 days'      AS "16_to_20_days",
          '21-25 days'      AS "21_to_25_days",
          '26-30 days'      AS "26_to_30_days",
          '31 or more days' AS "31_or_more_days"
        )
      );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-08
        • 1970-01-01
        • 2018-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多