WITH子句:仅包括每个表中的某些值

时间:2019-01-15 19:32:00

标签: sql oracle left-join

我正在尝试编写一个查询,该查询将获取每个“位置区域”中特定SKU的位置计数,然后是用于合并目的的所有位置的总数。

这是我用来尝试此操作的代码:

WITH 
    C0R_Count AS (
        SELECT sku_id, count(location_id) as Bulk_Count
        FROM Inventory
        where location_id like 'C0R%'
        group by sku_id),
    C0S_Count AS (
        SELECT sku_id, count(location_id) as Bin_Count
        FROM Inventory
        where location_id like 'C0S%'
        group by sku_id)
SELECT RANK() OVER (ORDER BY Bin_Count+Bulk_Count DESC)as Count_Rank,
        Inventory.sku_id, Bin_Count, Bulk_Count, 
        (Bin_Count+Bulk_Count) as Total_Count
FROM Inventory, C0R_Count, C0S_Count
WHERE client_id = 'SDRY-US' 
   and site_id = 'USCOL1' 
   and Inventory.Sku_id = C0R_Count.Sku_id 
   and Inventory.Sku_id = C0S_Count.Sku_id 
   and (Bin_Count+Bulk_Count) > 9
GROUP BY Inventory.sku_id, Bin_Count, Bulk_Count
;

这是怎么回事,结果仅包括同时具有 Bulk_Count Bin_Count 至少一个位置的SKU。

例如,有一个特定的SKU在223(装箱计数)位置显示,但未在Bulk_Count位置显示。这些是使用当前查询显示的最高结果,但是总数为223的SKU的排名为1,但由于“批量计数”为0而被排除了

COUNT_RANK  SKU_ID            BIN_COUNT  BULK_COUNT   TOTAL_COUNT
1           M10003NS-02A-.M    71        2                73
2           M10003NS-02A-.S    68        2                70
3           M10003NS-02A-.L    60        4                64
4           M10003NS-02A-.XL   61        2                63

使用显式联接符号添加了以下内容,并获得了相同的结果。


WITH 
    C0R_Count AS (
        SELECT /*+ materialize */ 
        sku_id, count(location_id) as Bulk_Count
        FROM Inventory
        where location_id like 'C0R%'
        group by sku_id),
    C0S_Count AS (
        SELECT /*+ materialize */ 
        sku_id, count(location_id) as Bin_Count
        FROM Inventory
        where location_id like 'C0S%'
        group by sku_id)
SELECT RANK() OVER (ORDER BY Bin_Count+Bulk_Count DESC)as Count_Rank,
       Inventory.sku_id, Bin_Count, Bulk_Count, 
       (Bin_Count+Bulk_Count) as Total_Count
FROM Inventory
Left Join C0R_Count
   on Inventory.Sku_id = C0R_Count.Sku_id
Left Join C0S_Count
   on Inventory.Sku_id = C0S_Count.Sku_id
WHERE 
   client_id = 'SDRY-US' 
   and site_id = 'USCOL1' 
   and (Bin_Count+Bulk_Count) > 9
GROUP BY Inventory.sku_id, Bin_Count, Bulk_Count
;

3 个答案:

答案 0 :(得分:1)

您的查询似乎比所需的复杂得多。您可以使用条件聚合来完成所有这些操作,而无需子查询或CTE:

select rank() over (order by sum(case when location_id like 'C0R%' or location_id like 'C0s%' then 1 else 0 end) desc) as count_rank,
       sku_id,
       sum(case when location_id like 'C0R%' then 1 else 0 end) as Bulk_Count
       sum(case when location_id like 'C0S%' then 1 else 0 end) as Bin_Count
from Inventory i
where client_id = 'SDRY-US' and site_id = 'USCOL1' 
group by sku_id
having sum(case when location_id like 'C0R%' or location_id like 'C0s%' then 1 else 0 end) > 9;

您可以引入子查询只是为了简化列别名:

select rank() over (order by Bulk_Count + Bin_Count desc) as count_rank,
       i.*
from (select sku_id,
             sum(case when location_id like 'C0R%' then 1 else 0 end) as Bulk_Count
             sum(case when location_id like 'C0S%' then 1 else 0 end) as Bin_Count
      from Inventory i
      where client_id = 'SDRY-US' and site_id = 'USCOL1' 
      group by sku_id
     ) i
where Bulk_Count + Bin_Count > 9

答案 1 :(得分:0)

我将继续将其发布为答案–您需要在此处使用LEFT/RIGHT JOIN语法。 DBMS将在逻辑上解释您现有的SQL,以隐式表示INNER联接。

此外,您可能需要重新考虑GROUP BY子句。

您可能需要使用子查询 –首先选择感兴趣的行,然后对其进行汇总。

答案 2 :(得分:0)

您可以尝试以下方法:

WITH 
    C0R_Count AS (
        SELECT /*+ materialize */ 
        sku_id, count(location_id) as Bulk_Count
        FROM Inventory
        where location_id like 'C0R%'
        group by sku_id),
    C0S_Count AS (
        SELECT /*+ materialize */ 
        sku_id, count(location_id) as Bin_Count
        FROM Inventory
        where location_id like 'C0S%'
        group by sku_id)
SELECT RANK() OVER (ORDER BY nvl(Bin_Count,0)+nvl(Bulk_Count,0) DESC)as Count_Rank,
       Inventory.sku_id, Bin_Count, Bulk_Count, 
       (nvl(Bin_Count,0)+nvl(Bulk_Count,0)) as Total_Count
FROM Inventory
Left Join C0R_Count
   on Inventory.Sku_id = C0R_Count.Sku_id
Left Join C0S_Count
   on Inventory.Sku_id = C0S_Count.Sku_id
WHERE 
   client_id = 'SDRY-US' 
   and site_id = 'USCOL1' 
   and (nvl(Bin_Count,0)+nvl(Bulk_Count,0)) > 9
GROUP BY Inventory.sku_id, Bin_Count, Bulk_Count
;

计算空值时,它们将成为空值。