需要找到自己拆分的交易

时间:2019-03-29 17:05:05

标签: sql oracle

我有一个SKU列表,它们在单独的表中只是POD。我需要找到其中包含POD SKU的交易以及具有POD SKU和其他一些SKU的交易。

我已经附加了我创建的示例数据库。

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=c2150662b298b8d172c6902514ada52a

这是这些表中的数据:

select * from transaction_detail_mv;

INDIVIDUAL_ID DOLLAR_VALUE_US   QUANTITY TRANSACTION_NUMBER SKU        TXN_DATE   BRAND   IS_MERCH CURRE L
------------- --------------- ---------- ------------------ ---------- ---------- ----- ---------- ----- -
            1              10         30                567 903633     2019-02-01 BRAND          1 USD   S
            1              20         30                567 123767     2019-02-01 BRAND          1 USD   S
            1              10         40                345 773633     2019-02-10 BRAND          1 USD   S
            1              12         30                345 965322     2019-02-10 BRAND          1 USD   S
            1              10         50                678 838364     2019-02-15 BRAND          1 USD   S
            1              10         70                975 983636     2019-02-28 BRAND          1 USD   S
            2              11         80                910 363635     2019-02-11 BRAND          1 USD   S
            2              11         90                323 566373     2019-02-12 BRAND          1 USD   S
            3              11         62                855 678364     2019-02-12 BRAND          1 USD   S
select * from POD_SKU;

SKU       
----------
903633
773633
838364
678364

例如,事务号567和345将被拆分为事务,因为它们每个都在同一事务中具有POD SKU以及一些其他SKU。事务975和855将是单个事务,因为它们只有POD SKU。

这是我正在寻找的格式:         txn_count sum(quantity) split 2 ? single 2 ?

1 个答案:

答案 0 :(得分:1)

您可以在表之间使用外部联接以同时包含POD和非POD SKU,然后使用案例表达式以及可能的分析(窗口式)函数在同一事务的各行之间进行比较;例如:

select td.transaction_number, td.sku,
  case when ps.sku is not null
       then 'Yes'
       else 'No'
  end as is_pod_sku,
  case when count(ps.sku) over (partition by td.transaction_number) > 0
       then 'Yes'
       else 'No'
  end as has_pod_sku,
  case when count(ps.sku) over (partition by td.transaction_number) > 0
       and  count(ps.sku) over (partition by td.transaction_number)
              < count(*) over (partition by td.transaction_number)
       then 'Yes'
       else 'No'
  end as is_split
from transaction_detail_mv td
left join pod_sku ps on ps.sku = td.sku;

TRANSACTION_NUMBER SKU        IS_POD_SKU HAS_POD_SKU IS_SPLIT
------------------ ---------- ---------- ----------- --------
               323 566373     No         No          No      
               345 773633     Yes        Yes         Yes     
               345 965322     No         Yes         Yes     
               567 123767     No         Yes         Yes     
               567 903633     Yes        Yes         Yes     
               678 838364     Yes        Yes         No      
               855 678364     Yes        Yes         No      
               910 363635     No         No          No      
               975 983636     No         No          No      

db<>fiddle

然后您可以过滤掉has_pod_sku为“否”的内容。显然(希望)您可以包括原始表中想要的任何列,我刚刚显示了此时似乎最相关的两列。如果使用“是”和“否”,则可以使用0/1或Y / N标志或更多描述性文本。详细信息取决于您最终想要看到的内容。


  

有没有一种方法可以对它们进行计数

您可以将上面的查询用作子查询并计算每个标志值(在排除完全没有POD SKU的那些标志之后):

select count(distinct case when is_split = 'Yes' then transaction_number end) as split,
  count(distinct case when is_split = 'No' then transaction_number end) as single
from (
  select td.transaction_number, td.sku,
    case when count(ps.sku) over (partition by td.transaction_number) > 0
         then 'Yes'
         else 'No'
    end as has_pod_sku,
    case when count(ps.sku) over (partition by td.transaction_number) > 0
         and  count(ps.sku) over (partition by td.transaction_number)
                < count(*) over (partition by td.transaction_number)
         then 'Yes'
         else 'No'
    end as is_split
  from transaction_detail_mv td
  left join pod_sku ps on ps.sku = td.sku
)
where has_pod_sku = 'Yes';

     SPLIT     SINGLE
---------- ----------
         2          2

或更简单地说:

select count(case when sku_count > pod_sku_count then transaction_number end) as split,
  count(case when sku_count = pod_sku_count then transaction_number end) as single
from (
  select td.transaction_number,
    count(*) as sku_count,
    count(ps.sku) as pod_sku_count
  from transaction_detail_mv td
  left join pod_sku ps on ps.sku = td.sku
  group by td.transaction_number
)
where pod_sku_count > 0;

     SPLIT     SINGLE
---------- ----------
         2          2

db<>fiddle,其中添加了这两个查询。