oracle 根据列中值返回限制行数

3wabscal  于 2022-11-28  发布在  Oracle
关注(0)|答案(2)|浏览(236)

我有一段代码:

SELECT t1.sku_id, t1.putaway_group, t1.shortage, t4.location_id, t4.qty_on_hand
    FROM 
    (WHERE clauses)t1
   
LEFT JOIN
        (
        SELECT *
        FROM   (
          SELECT location_id, sku_id, qty_on_hand,
                DENSE_RANK() OVER ( PARTITION BY sku_id ORDER BY qty_on_hand DESC ) AS rnk
          FROM   inventory
          WHERE substr(zone_1,1,5) IN ('TOTEB','TOTEC')
        )
        WHERE  rnk = 1
        ORDER BY 2 DESC
        )t4
        ON t3.sku_id = t4.sku_id

其中输出为:

我想要实现的是从location_id返回短缺所需的行数。例如,如果短缺为-84,则将THEN作为SKU的输出:02295441我想返回6行,因为(6*16 = 96)这将弥补我的不足。不太确定是否可能,或者如果是,那么如何写一个where/having子句来限制输出行。目前我只是通过excel中的power query来做,但只是想知道是否可能直接从sql中。提前感谢。

ego6inou

ego6inou1#

You can use the SUM analytic function:

SELECT t1.sku_id,
       t1.putaway_group,
       t1.shortage,
       t4.location_id,
       t4.qty_on_hand
FROM   /*(WHERE clauses)*/ t1
       LEFT JOIN (
         SELECT location_id,
                sku_id,
                qty_on_hand,
                SUM(qty_on_hand) OVER (
                  PARTITION BY sku_id
                  ORDER BY qty_on_hand DESC, ROWNUM
                ) AS total_qty
         FROM   inventory
         WHERE  zone_1 LIKE 'TOTEB%'
         OR     zone_1 LIKE 'TOTEC%'
       ) t4
       ON (   t1.sku_id = t4.sku_id
          AND -t1.shortage > t4.total_qty - t4.qty_on_hand )

Which, for the sample data:

CREATE TABLE t1 (sku_id, putaway_group, shortage) AS
SELECT 'SKU1', 'TEXTILES', -84 FROM DUAL UNION ALL
SELECT 'SKU2', 'PLASTICS', -13 FROM DUAL;

CREATE TABLE inventory(location_id, sku_id, qty_on_hand, zone_1) AS
SELECT LEVEL, 'SKU1', LEAST(LEVEL * 4, 16), 'TOTEB' || CHR(64 + LEVEL) FROM DUAL CONNECT BY LEVEL <= 10
UNION ALL
SELECT LEVEL, 'SKU2', LEVEL, 'TOTEC' || CHR(64 + LEVEL) FROM DUAL CONNECT BY LEVEL <= 6;

Outputs:
| SKU_ID | PUTAWAY_GROUP | SHORTAGE | LOCATION_ID | QTY_ON_HAND |
| ------------ | ------------ | ------------ | ------------ | ------------ |
| SKU1 | TEXTILES | -84 | 4 | 16 |
| SKU1 | TEXTILES | -84 | 5 | 16 |
| SKU1 | TEXTILES | -84 | 6 | 16 |
| SKU1 | TEXTILES | -84 | 7 | 16 |
| SKU1 | TEXTILES | -84 | 8 | 16 |
| SKU1 | TEXTILES | -84 | 9 | 16 |
| SKU2 | PLASTICS | -13 | 6 | 6 |
| SKU2 | PLASTICS | -13 | 5 | 5 |
| SKU2 | PLASTICS | -13 | 4 | 4 |
fiddle

l7wslrjt

l7wslrjt2#

由于缺乏样本数据,我的CTE代表(简化)结果,你目前有;如果对它应用row_number函数,然后返回满足所述条件的行(参见第22行),则可能得到所需结果:

SQL> with data (sku_id, shortage, location_id, qty_on_hand) as
  2    (select 1, -84, 3, 16 from dual union all
  3     select 1, -84, 2, 16 from dual union all
  4     select 1, -84, 5, 16 from dual union all
  5     select 1, -84, 5, 16 from dual union all
  6     select 1, -84, 5, 16 from dual union all
  7     select 1, -84, 6, 16 from dual union all
  8     select 1, -84, 1, 16 from dual union all
  9     select 1, -84, 2, 16 from dual union all
 10     select 1, -84, 1, 16 from dual union all
 11     select 1, -84, 2, 16 from dual union all
 12     --
 13     select 2, -20, 1, 10 from dual
 14    ),
 15  temp as
 16    (select d.*,
 17       row_number() over (partition by sku_id order by qty_on_hand) rnk
 18       from data d
 19    )
 20  select *
 21  from temp
 22  where rnk <= ceil(abs(shortage) / qty_on_hand);

    SKU_ID   SHORTAGE LOCATION_ID QTY_ON_HAND        RNK
---------- ---------- ----------- ----------- ----------
         1        -84           3          16          1  --> SKU_ID = 1 begins here
         1        -84           2          16          2
         1        -84           5          16          3
         1        -84           5          16          4
         1        -84           5          16          5
         1        -84           6          16          6  --> SKU_ID = 1 ends here; 6 rows
         2        -20           1          10          1

7 rows selected.

SQL>

相关问题