使用联合过滤器创建重复项

时间:2019-03-26 19:17:45

标签: sql oracle

我想复制我的数据,但在一栏中更改一个值。例如,我需要我的数据在每个(到)和(从)中都看起来像这样。

  to    from    vehicle size    l   h
 FCS011 FCS416  6025         0.1       0.3
 FCS011 FCS416  6020         0.1    0.3
 FCS011 FCS416  6010         0.1    0.3
 FCS011 FCS416  6015         0.1    0.3

现在对于某些(到)和(从)集,我只有车辆大小为6010和6015的数据,而对于某些我只有6025和6020的数据。我需要复制缺少的给定集合的值一个或另一个集合的数据。

对于某些集合(market_to,market_from),我的数据当前看起来像这样

 to     from    vehicle size    l     h
 FCS010 FCS416  6025         0.1       0.3
 FCS010 FCS416  6020         0.1       0.3
 FCS012 FCS416  6010         0.1       0.3
 FCS012 FCS416  6015         0.1       0.3

此数据集应如下所示:

      to      from  vehicle size    l       h
      FCS010    FCS416  6025         0.1       0.3
      FCS010    FCS416  6020         0.1       0.3
      FCS010    FCS416  6010         0.1       0.3
      FCS010    FCS416  6015         0.1       0.3
      FCS012    FCS416  6010         0.1       0.3
      FCS012    FCS416  6015         0.1       0.3
      FCS012    FCS416  6020         0.1       0.3
      FCS012    FCS416  6025         0.1       0.3

因此,我想全部合并,以捕获其他值,但是我不确定如何捕获其一个或另一个的逻辑。以下是我的查询,我做了一个联合以创建额外的行。

 create table PA_FCS_temp
 as
 select 
 MARKET_FROM ,
 MARKET_TO ,
 VEHICLE_CLASS,
 l,
 h
 from PA_FCS
 UNION ALL
 select MARKET_FROM ,
 MARKET_TO ,
 decode(VEHICLE_CLASS, '6020', '6025', '6010', '6015') as VEHICLE_CLASS,        
 l,
 h

 from PA_FCS
 VEHICLE_CLASS in ('6020', '6010')

 ORDER BY MARKET_FROM, MARKET_TO;

2 个答案:

答案 0 :(得分:1)

通过使用带有 cross join as

的模块化逻辑,可以多路复用仅以560156025)结尾的记录
select * from t where mod(vehicle_size,10)=0
union all
select t1.* 
  from t t1 cross join t t2 
 where mod(t1.vehicle_size,5)=0
   and mod(t1.vehicle_size,10)!=0

Demo

答案 1 :(得分:0)

思考问题的一种方法不是“重复行”,而是“填充稀疏数据”。

您有一个已知车辆尺寸的列表:6010、6015、6020和6025。您有market_tomarket_from给出的数据集,其中每个数据集可能不包含所有已知的车辆尺寸。您想要填写稀疏数据,以便每个集合都包含每种已知的车辆尺寸。

Oracle中用于填充稀疏数据的一个很好的SQL工具是“分区的”外部联接。这是您的查询的工作方式:

设置

CREATE TABLE market_data (  
  market_to varchar2(6), 
  market_from varchar2(6), 
  vehicle_size number(4),
  l number,
  h number);

INSERT INTO market_data
 SELECT 'FCS010','FCS416',6025,  0.1, 0.3 FROM DUAL UNION ALL
 SELECT 'FCS010','FCS416',6020,  0.1, 0.3 FROM DUAL UNION ALL
 SELECT 'FCS012','FCS416',6010,  0.1, 0.3 FROM DUAL UNION ALL
 SELECT 'FCS012','FCS416',6015,  0.1, 0.3 FROM DUAL ;

 COMMIT;

分区外部联接查询

(注意:如果您有一个表,该表具有已知的车辆尺寸,则可以使用该表并省略WITH子句。)

with vehicle_sizes ( vehicle_size ) AS 
  ( SELECT column_value FROM TABLE(sys.odcinumberlist(6010, 6015, 6020, 6025)) )
select md.market_from, 
       md.market_to,
       vs.vehicle_size,
       nvl(md.l, min(md.l) over ( partition by md.market_from, md.market_to )) l,
       nvl(md.h, min(md.h) over ( partition by md.market_from, md.market_to )) h
from market_data md partition by (md.market_to, md.market_from) 
right outer join vehicle_sizes vs on vs.vehicle_size = md.vehicle_size;
+-------------+-----------+--------------+-----+-----+
| MARKET_FROM | MARKET_TO | VEHICLE_SIZE |  L  |  H  |
+-------------+-----------+--------------+-----+-----+
| FCS416      | FCS010    |         6010 | 0.1 | 0.3 |
| FCS416      | FCS010    |         6015 | 0.1 | 0.3 |
| FCS416      | FCS010    |         6020 | 0.1 | 0.3 |
| FCS416      | FCS010    |         6025 | 0.1 | 0.3 |
| FCS416      | FCS012    |         6010 | 0.1 | 0.3 |
| FCS416      | FCS012    |         6015 | 0.1 | 0.3 |
| FCS416      | FCS012    |         6020 | 0.1 | 0.3 |
| FCS416      | FCS012    |         6025 | 0.1 | 0.3 |
+-------------+-----------+--------------+-----+-----+