选择供应商、部件组合的第一个实例

Selecting the first instance of a vendor, part combination

我正在尝试创建一个指标,以判断特定交易是否是第一次从特定供应商处购买零件。

我有一个如下所示的数据集:

| transaction_id | vendor_id | part_id |     trans_date    |
|:--------------:|:---------:|:-------:|:-----------------:|
|    9Bx*2Pc'    |     a     |   873   |     10/12/2018    |
|    1Po.4Ot,    |     a     |   473   |     4/22/2016     |
|    9Sk"7Kv/    |     b     |   123   |     7/23/2016     |
|    2Lz&7Hu&    |     a     |   873   |     12/20/2017    |
|    8Lz)5Is#    |     b     |   743   |     10/22/2016    |
|    5Sc'6Jl/    |     a     |   113   |     10/6/2016     |
|    0Ra&8Hb&    |     a     |   653   |     10/4/2017     |
|    4Wc-8Of*    |     c     |   333   |      8/3/2017     |
|    8Vv+9Yo/    |     c     |   333   |     12/7/2016     |
|    6Qh!1Ha-    |     c     |   333   |     3/28/2017     |
|    2Ol%4Rs#    |     c     |   333   |      5/2/2017     |
|    1Gg#8Cm%    |     c     |   333   |     11/15/2016    |
|    0Lw(6Pv/    |     d     |   873   |     8/13/2017     |
|    1Gy/7Zw,    |     a     |   443   |     10/12/2018    |
|    2Gz,4Gp.    |     b     |   103   |      1/5/2018     |
|    5Dj)6Wc+    |     a     |   893   |     12/17/2016    |
|    5Hl-8Ds!    |     a     |   903   |     12/8/2017     |
|    8WsVy*    |     b     |   873   |     1/13/2018     |

我要做的是确定 transaction_id 是否是 第一次 (按 trans_date 排序),part_id 是从 vendor_id 购买的。我会想象理想的输出看起来像这样:

| transaction_id | vendor_id | part_id |     trans_date    | first_time |
|:--------------:|:---------:|:-------:|:-----------------:|:----------:|
|    9Bx*2Pc'    |     a     |   873   |     10/12/2018    |      N     |
|    1Po.4Ot,    |     a     |   473   |     4/22/2016     |      Y     |
|    9Sk"7Kv/    |     b     |   123   |     7/23/2016     |      Y     |
|    2Lz&7Hu&    |     a     |   873   |     12/20/2017    |      Y     |
|    8Lz)5Is#    |     b     |   743   |     10/22/2016    |      Y     |
|    5Sc'6Jl/    |     a     |   113   |     10/6/2016     |      Y     |
|    0Ra&8Hb&    |     a     |   653   |     10/4/2017     |      Y     |
|    4Wc-8Of*    |     c     |   333   |      8/3/2017     |      N     |
|    8Vv+9Yo/    |     c     |   333   |     12/7/2016     |      N     |
|    6Qh!1Ha-    |     c     |   333   |     3/28/2017     |      N     |
|    2Ol%4Rs#    |     c     |   333   |      5/2/2017     |      N     |
|    1Gg#8Cm%    |     c     |   333   |     11/15/2016    |      Y     |
|    0Lw(6Pv/    |     d     |   873   |     8/13/2017     |      Y     |
|    1Gy/7Zw,    |     a     |   443   |     10/12/2018    |      Y     |
|    2Gz,4Gp.    |     b     |   103   |      1/5/2018     |      Y     |
|    5Dj)6Wc+    |     a     |   893   |     12/17/2016    |      Y     |
|    5Hl-8Ds!    |     a     |   903   |     12/8/2017     |      Y     |
|    8WsVy*    |     b     |   873   |     1/13/2018     |      Y     |

到目前为止,我已经尝试过(受this post影响):

WITH
  first_instance AS (
    SELECT
      tbl_trans.*,
      ROW_NUMBER() OVER (PARTITION BY vendor_id||part_id ORDER BY trans_date) AS row_nums
    FROM
      tbl_trans
 )
 
 SELECT
   x.*,
   CASE WHEN y.row_nums = 1 THEN 'Y' ELSE 'N' END AS first_time_indicator
 FROM
   tbl_trans x
     LEFT JOIN first_instance y

但我遇到了:

ORA-00905: missing keyword

到目前为止,我已经使用这些数据和查询创建了一个 SQL FIDDLE 用于测试。 如何确定交易是否是第一次购买 part/vendor 组合?

使用window函数:

select t.*,
       (case when row_number() over (partition by vendor_id, part_id order by trans_date) = 1
             then 'Y' else 'N'
        end) as first_time
from tbl_trans t;

您不需要 join

除了row_number之外,还有以下多种方法可以使用分析函数实现所需的结果。

您可以使用first_value解析函数如下:

Select t.*,
       Case 
         when first_value(trans_date) 
                over (partition by vendor_id, part_id order by trans_date) = trans_date
         then 'Y' 
         else 'N' 
       end as first_time
From your_table t;

同理,也可以使用min如下:

Select t.*,
       Case 
         when min(trans_date) 
                over (partition by vendor_id, part_id) = trans_date
         then 'Y' 
         else 'N' 
       end as first_time
From your_table t;