【问题标题】:Searching a value in a string in PostgreSQL在 PostgreSQL 中搜索字符串中的值
【发布时间】:2020-01-27 21:59:28
【问题描述】:

我有一个在 Magento(1.9) 上运行的网站,并且需要了解客户再次购买相同产品的平均时间以及购买相同产品的客户百分比。

订单表(Sales_flat_order) - 包含订单详情 列 - order_id、Created_date、Customer_email

Items 表(Sales_Flat_Order_item) - 特定订单中的项目,如果用户购买 6 个项目,则项目表将有 6 个具有相同 order_id 的条目。 列 - items_id,Order_id(FK),item_sku(不同的产品)

下面是我加入了按电子邮件 ID 过滤的特定客户的订单和商品表的示例数据。

例如 order_id "92224" 有 4 行表示在该订单中购买了 4 件商品,item_sku 指的是商品名称/其唯一 ID。

现在我想找出再次购买相同产品的平均时间。所以在订单“98651”中,用户购买了第一个订单中的产品 items_sku("2996")。所以平均时间将是这两个订单之间的日期差。

以下是我面临的困难,

1) 由于每个订单可以包含多个产品,因此我如何将商品行与之前的订单商品进行比较。我尝试使用 LIKE 和 ILIKE,但它似乎不起作用并尝试使用 STR_AGG(item_sku,' ,') 与 LIKE 但没有找到任何结果。

2) 不仅针对特定客户,还需要针对每一位客户。

Order_id     Order_date         Item_sku
92224   "2016-11-11 17:18:15"   "3001"
92224   "2016-11-11 17:18:15"   "2933"
92224   "2016-11-11 17:18:15"   "2992-config"
92224   "2016-11-11 17:18:15"   "2996"
94926   "2016-11-25 10:01:30"   "3008"
98651   "2016-12-14 18:11:16"   "2992-config"
98651   "2016-12-14 18:11:16"   "2996"
99645   "2016-12-20 13:00:34"   "3001"
99645   "2016-12-20 13:00:34"   "2933"
114578  "2017-02-28 15:32:54"   "2931"
114578  "2017-02-28 15:32:54"   "0294"
114578  "2017-02-28 15:32:54"   "0297"
114578  "2017-02-28 15:32:54"   "0296"
114578  "2017-02-28 15:32:54"   "2992-config"
131754  "2017-05-15 17:23:35"   "3296"
131968  "2017-05-16 18:30:52"   "3300"
133186  "2017-05-22 14:03:07"   "3004"
133186  "2017-05-22 14:03:07"   "3069-bio"
133186  "2017-05-22 14:03:07"   "3421-bio-config"
137484  "2017-06-13 14:07:28"   "3605"
137484  "2017-06-13 14:07:28"   "3604"
141709  "2017-07-03 16:20:30"   "3603"
141709  "2017-07-03 16:20:30"   "3606"
141709  "2017-07-03 16:20:30"   "2936"
141709  "2017-07-03 16:20:30"   "3422-bio"
141977  "2017-07-04 16:31:37"   "2936"
145194  "2017-07-17 15:22:41"   "3603"
145194  "2017-07-17 15:22:41"   "3604"
151651  "2017-08-11 11:43:38"   "3809"
161334  "2017-09-14 15:53:30"   "3670"
161334  "2017-09-14 15:53:30"   "3604"
161334  "2017-09-14 15:53:30"   "3603"

任何指导都会有很大帮助。我使用 PostgreSQL 作为我的数据库。

【问题讨论】:

    标签: postgresql magento magento-1.9


    【解决方案1】:

    我对magento一无所知,但考虑到您的输入数据,这就是我在postgres中解决这个问题的方法:

    SELECT item_sku, avg(elapsed_s) as avg_s
    FROM (
      select order_id, 
             order_date, 
             item_sku, 
             extract(epoch from (order_date - lag(order_date) 
                OVER (partition by item_sku order by order_date))) as elapsed_s
      FROM orders
    ) sub
    WHERE elapsed_s IS NOT NULL
    GROUP BY item_sku
    ;
      item_sku   |    avg
    -------------+-----------
     2933        |   3354139
     2936        |     87067
     2992-config | 4705639.5
     2996        |   2854381
     3001        |   3354139
     3603        |   3152790
     3604        |   4020781
    (7 rows)
    

    这是购买同一商品之间的平均时间(以秒为单位)。在内部查询中,我们使用按 item_sku 分区的滞后窗口函数来比较当前行与该项目的前一个条目。外部查询仅按 item_sku 分组。

    如果您要添加多个用户,只需将 partition by 子句更改为 partition by user_id, item_sku,然后按 user_id 和 item_sku 进行分组。

    【讨论】:

    • 非常感谢您的及时回复,这个查询只会检查以前的订单,对吗?表示客户是否在之前的订单中购买过相同的产品?
    • 这将得到客户购买产品然后再次购买相同产品之间的差异,无论这两个订单之间有多少订单。客户是否必须在下一个订单中再次购买该产品?
    • 不,不要排在第二位。感谢您的回复:)真的很有帮助。
    • 那么什么是用户在超过2个订单中订购了相同的商品,意味着用户在连续5个订单中购买了相同的产品,所以使用lag不会得到确切的结果对吗?
    • lag 将计算同一产品的两个连续订单之间的时间差。我们计算同一产品的每个订单之间的差异,并使用avggroup by 计算订单之间的平均时间。 2992-config 被订购了 3 次,这就是为什么 avg_s 不是整数的原因。
    【解决方案2】:

    @Jeremy 实际上提供了一个很好的例程,只是结果以经过的秒数为单位。但是,这可能不是最有用的格式。您可以直接使用日期减法和间隔,而不是使用纪元。

    select item_sku
         , extract('days' from average_time) || ' days ' ||  extract('hour' from average_time) || ' hours' average_time
      from (    
            select item_sku,avg(intv) average_time   
              from (
                    select order_date, 
                           item_sku, 
                           (order_date - lag(order_date) 
                                         OVER (partition by item_sku order by order_date)) as intv
                      FROM sales_flat_order_item
                   ) intv_diff
             where intv is not null
             group by item_sku
             order by item_sku) avg_time; 
    

    最外面的查询只是将结果格式化为天和小时。没有它,结果可能会出现(并且会出现)到小数秒。

    【讨论】:

    • 非常感谢,但是这个查询只会检查上一个订单对吗?意思是客户是否在上一个订单中购买了相同的产品?
    猜你喜欢
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多