交叉销售矩阵 - 在雪花

时间:2021-03-16 12:53:55

标签: sql matrix pivot snowflake-cloud-data-platform

我正在尝试构建一个交叉销售矩阵,其结构如下所示,其中 X 是其他产品在篮子中的频率百分比:

Cross Sell Matrix

之后我需要在 excel 或其他工具中对这些数据进行透视,因此我假设 Snowflake 中的查询需要输出准备好进行透视的表格数据集,而我正在为它的逻辑而苦苦挣扎。

这是我目前所拥有的:

SELECT FCT.TRANSACTION_ID,
   PRD.PRODUCT_TYPE,
   COUNT(DISTINCT FCT.PRODUCT_ID),
   COUNT(DISTINCT FCT1.PRODUCT_ID)
FROM TRANSACTION_ORDERS FCT
     INNER JOIN DIM_PRODUCT PRD ON FCT.PRODUCT_ID = PRD.PRODUCT_ID
     LEFT JOIN FACT_TRANSACTION_ORDERS FCT1 ON FCT.TRANSACTION_ID = FCT1.TRANSACTION_ID
                                            AND FCT.PRODUCT_ID != FCT1.PRODUCT_ID
GROUP BY FCT.TRANSACTION_ID, FCT.PRODUCT_ID, FCT1.PRODUCT_ID

加入是否正确?或者我应该做一个交叉连接?另外,如何捕获同一篮子中两种产品的百分比频率?

非常感谢!

编辑:我正在尝试捕捉出现在同一购物篮中的不同产品类型的频率。

两个方向的组合的值相同。 ProductType1 与列 ProductType2 的交集与列 Product Type1 行 ProductType2 的值相同。

在篮子交叉分析中,它们应该有所不同。每个方向都不一样。换句话说,具有 ProductType1 的篮子可能有 X% 的时间具有 ProductType2,但具有 ProductType2 的篮子应该有 Y% 的时间具有 ProductType1。

1 个答案:

答案 0 :(得分:1)

您想要自连接。我希望产品具有相同的订单,但您似乎使用了相同的交易。无论如何,这是查询的结构:

WITH TP AS (
      SELECT T.*, P.PRODUCT_TYPE
      FROM TRANSACTION_ORDERS T JOIN
            DIM_PRODUCT P
            ON T.PRODUCT_ID = P.PRODUCT_ID
     )
SELECT TP.PRODUCT_TYPE, TP2.PRODUCT_TYPE,
       COUNT(DISTINCT TP.TRANSACTION_ID) as NUM_ORDERS
FROM TP JOIN
     TP TP2
     ON TP2.TRANSACTION_ID = TP.TRANSACTION_ID
GROUP BY TP.PRODUCT_TYPE, TP2.PRODUCT_TYPE;

如果这是每个订单,您只需将外部查询中的 ON 子句更改为使用订单 ID。

请注意,这里使用 COUNT(DISTINCT) 而不是 COUNT(*),因为交易/订单可能有多个相同类型的产品。据推测,您希望只计算一次。

编辑:

如果你想除以具有任一产品类型的交易数量(这对我来说很有意义),那么我会这样处理:

WITH TP AS (
      SELECT DISTINCT T.TRANSACTION_ID, P.PRODUCT_TYPE
      FROM TRANSACTION_ORDERS T JOIN
            DIM_PRODUCT P
            ON T.PRODUCT_ID = P.PRODUCT_ID
     )
SELECT TP.PRODUCT_TYPE, TP2.PRODUCT_TYPE,
       COUNT(*) as NUM_ORDERS,
       ( MAX(CASE WHEN TP.PRODUCT_TYPE = TP2.PRODUCT_TYPE THEN COUNT(*) END) OVER (PARTITION BY TP.PRODUCT_TYPE) +
         MAX(CASE WHEN TP.PRODUCT_TYPE = TP2.PRODUCT_TYPE THEN COUNT(*) END) OVER (PARTITION BY TP2.PRODUCT_TYPE) -
         COUNT(*)
       ) as Num_Orders_Either,
       ( COUNT(*) * 1.0 /
         ( MAX(CASE WHEN TP.PRODUCT_TYPE = TP2.PRODUCT_TYPE THEN COUNT(*) END) OVER (PARTITION BY TP.PRODUCT_TYPE) +
           MAX(CASE WHEN TP.PRODUCT_TYPE = TP2.PRODUCT_TYPE THEN COUNT(*) END) OVER (PARTITION BY TP2.PRODUCT_TYPE) -
           COUNT(*)
       ) as ratio
FROM TP JOIN
     TP TP2
     ON TP2.TRANSACTION_ID = TP.TRANSACTION_ID
GROUP BY TP.PRODUCT_TYPE, TP2.PRODUCT_TYPE;

这会计算包含两种产品的订单总数,其中任一产品的订单总和减去两者的数量。