【问题标题】:How do I make this MySQL query faster and better?如何使这个 MySQL 查询更快更好?
【发布时间】:2022-01-13 00:36:36
【问题描述】:

我有这个查询,我现在正试图加快速度 - 除非我将 WHERE customers.total_orders >= 1 更改为 WHERE customers.total_orders = 1,否则它会超时。

本质上,查询应该显示客户第一次、第二次、第三次、第四次、第五次和第六次下达的客户总数以及每次订单的平均值。中间时间是客户下另一个订单之前的平均时间。

我要回答的问题是,如果客户订购了 X 产品,那么他们的生命周期价值是多少。

SELECT

  count(o1_id) as "Total-O1",
  avg(o1_total) as "Order Value-O1",
  avg(TimeDiff_o1) as "Avg-o1-o2(Days)",

  count(o2_id) as "Total-o2",
  avg(o2_total) as "Order Value-o2",
  avg(TimeDiff_o2) as "Avg-o2-o3(Days)",

  count(o3_id) as "Total-o3",
  avg(o3_total) as "Order Value-o3",
  avg(TimeDiff_o3) as "Avg-o3-o4(Days)",

  count(o4_id) as "Total-o4",
  avg(o4_total) as "Order Value-o4",
  avg(TimeDiff_o4) as "Avg-o4-o5(Days)",

  count(o5_id) as "Total-o5",
  avg(o5_total) as "Order Value-o5"

FROM (
   SELECT 
       o1.id as o1_id,
       o1.mc_gross AS o1_total,
       timestampdiff(DAY,o1.purchased_at,o2.purchased_at) AS TimeDiff_o1,

       o2.id as o2_id,
       o2.mc_gross AS o2_total,
       timestampdiff(DAY,o2.purchased_at,o3.purchased_at) AS TimeDiff_o2,

       o3.id as o3_id,
       o3.mc_gross AS o3_total,
       timestampdiff(DAY,o3.purchased_at,o4.purchased_at) AS TimeDiff_o3,

       o4.id as o4_id,
       o4.mc_gross AS o4_total,
       timestampdiff(DAY,o4.purchased_at,o5.purchased_at) AS TimeDiff_o4,

       o5.id as o5_id,
       o5.mc_gross AS o5_total,
       timestampdiff(DAY,o5.purchased_at,o6.purchased_at) AS TimeDiff_o5,

       o6.id as o6_id,
       o6.mc_gross AS o6_total

    FROM customers

    cross join orders as o1 on o1.customer_id = customers.id and o1.store_id = 10 and customers.created_at >= curdate() - interval 365 day

    cross join order_items o1_order_items ON o1_order_items.order_id = o1.id and o1_order_items.product_variant_id = 1

    LEFT JOIN orders o2 ON o2.customer_id = customers.id
        AND o2.store_id = 10
        AND o2.parent_order_id = 0
        AND o2.id != o1.id
    LEFT JOIN orders o3 ON o3.customer_id = customers.id
        AND o3.store_id = 10
        AND o3.parent_order_id = 0
        AND o3.id != o1.id
        AND o3.id != o2.id
    LEFT JOIN orders o4 ON o4.customer_id = customers.id
        AND o4.store_id = 10
        AND o4.parent_order_id = 0
        AND o4.id != o1.id
        AND o4.id != o2.id
        AND o4.id != o3.id
    LEFT JOIN orders o5 ON o5.customer_id = customers.id
        AND o5.store_id = 10
        AND o5.parent_order_id = 0
        AND o5.id != o1.id
        AND o5.id != o2.id
        AND o5.id != o3.id
        AND o5.id != o4.id
    LEFT JOIN orders o6 ON o6.customer_id = customers.id
        AND o6.store_id = 10
        AND o6.parent_order_id = 0
        AND o6.id != o1.id
        AND o6.id != o2.id
        AND o6.id != o3.id
        AND o6.id != o4.id
        AND o6.id != o5.id

    WHERE customers.total_orders >= 1

    group by customers.id

) as a
CREATE TABLE `customers` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `address_city` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_country` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_country_code` varchar(2) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_name` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_firstname` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_state` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_status` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_street` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_zip` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `first_name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `last_name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `instagram_username` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
  `payer_business_name` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `payer_email` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `payer_id` varchar(13) COLLATE utf8_unicode_ci DEFAULT NULL,
  `payer_status` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `contact_phone` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `sanitized_phone` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `sanitized_phone_last_10` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `residence_country` varchar(2) COLLATE utf8_unicode_ci DEFAULT NULL,
  `username` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `first_order_id` int(11) DEFAULT '0',
  `last_order_id` int(11) DEFAULT '0',
  `total_orders` int(11) DEFAULT '0',
  `total_gross` decimal(8,2) DEFAULT '0.00',
  `avatar` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'http://lorempixel.com/200/200/',
  `oauth_avatar` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `auth_type` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `subscr_id` varchar(19) COLLATE utf8_unicode_ci DEFAULT NULL,
  `type` enum('default','wholesale') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'default',
  `verified` tinyint(1) DEFAULT NULL,
  `verify_token` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL,
  `remember_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `last_login_at` timestamp NULL DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `deleted_at` timestamp NULL DEFAULT NULL,
  `promotion_opt_in` tinyint(1) NOT NULL DEFAULT '0',
  `marketing_sms_opt_in` tinyint(1) DEFAULT NULL,
  `referral_code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  `date_of_birth` date DEFAULT NULL,
  `updated_on_st_at` timestamp NULL DEFAULT NULL,
  `send_survey_email` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `customers_address_city_index` (`address_city`),
  KEY `customers_address_country_index` (`address_country`),
  KEY `customers_address_country_code_index` (`address_country_code`),
  KEY `customers_address_state_index` (`address_state`),
  KEY `customers_address_zip_index` (`address_zip`),
  KEY `customers_first_name_index` (`first_name`),
  KEY `customers_last_name_index` (`last_name`),
  KEY `customers_payer_email_index` (`payer_email`),
  KEY `customers_residence_country_index` (`residence_country`),
  KEY `customers_contact_phone_index` (`contact_phone`),
  KEY `customers_payer_business_name_index` (`payer_business_name`),
  KEY `customers_address_street_index` (`address_street`),
  KEY `customers_address_name_index` (`address_name`),
  KEY `deleted_at` (`deleted_at`),
  KEY `promotion_opt_in` (`promotion_opt_in`),
  KEY `type` (`type`),
  KEY `first_order_id` (`first_order_id`),
  KEY `sanitized_phone` (`sanitized_phone`),
  KEY `sanitized_phone_last_10` (`sanitized_phone_last_10`)
) ENGINE=InnoDB AUTO_INCREMENT=1361589 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `orders` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `warehouse_id` int(11) DEFAULT NULL,
  `external_order_id` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  `whs_order_id` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  `txn_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `customer_id` int(11) NOT NULL,
  `address_id` int(11) DEFAULT NULL,
  `payment_profile_id` int(11) DEFAULT NULL,
  `payment_status_id` int(11) NOT NULL,
  `shipping_service_id` int(11) DEFAULT NULL,
  `shipping_service_option_id` int(11) DEFAULT NULL,
  `pricing_cost_id` int(11) DEFAULT NULL,
  `subscription_group_id` int(11) DEFAULT NULL,
  `fulfillment_note` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
  `fulfillment_status_id` int(10) unsigned NOT NULL,
  `fulfillment_status_note` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
  `fulfilled_at` timestamp NULL DEFAULT NULL,
  `shipment_status_id` int(11) NOT NULL,
  `order_status_id` int(11) NOT NULL,
  `agent_id` int(11) NOT NULL,
  `store_id` int(11) NOT NULL,
  `parent_order_id` int(11) NOT NULL,
  `custom` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `memo` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `tax` decimal(9,2) DEFAULT NULL,
  `order_status_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `status_short_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `payment_date` varchar(28) COLLATE utf8_unicode_ci DEFAULT NULL,
  `shipping_method` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  `shipping` varchar(9) COLLATE utf8_unicode_ci DEFAULT NULL,
  `shipping_priority` tinyint(4) DEFAULT NULL,
  `exchange_rate` varchar(9) COLLATE utf8_unicode_ci DEFAULT NULL,
  `mc_currency` varchar(3) COLLATE utf8_unicode_ci DEFAULT NULL,
  `mc_fee` double(8,2) DEFAULT '0.00',
  `mc_gross` double(8,2) DEFAULT '0.00',
  `mc_handling` double(8,2) DEFAULT '0.00',
  `mc_shipping` double(8,2) DEFAULT '0.00',
  `mc_discount` double(8,2) DEFAULT '0.00',
  `mc_store_credit` double(8,2) DEFAULT '0.00',
  `total` double(8,2) DEFAULT NULL,
  `address_name` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_email` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_company` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_street` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_city` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_state` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_zip` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_country_code` varchar(2) COLLATE utf8_unicode_ci DEFAULT NULL,
  `address_phone` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `fulfillment_provider_id` int(11) DEFAULT NULL,
  `fulfillment_provider_order_id` int(11) DEFAULT NULL,
  `ship_after` timestamp NULL DEFAULT NULL,
  `confirmed_at` timestamp NULL DEFAULT NULL,
  `agentupdated_at` timestamp NULL DEFAULT NULL,
  `purchased_at` timestamp NULL DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  `delay_notice_sent_at` timestamp NULL DEFAULT NULL,
  `cost_of_goods_sold` decimal(8,2) NOT NULL DEFAULT '0.00',
  `use_store_credit` tinyint(1) DEFAULT NULL,
  `recurring_shipping_option` tinyint(1) DEFAULT NULL,
  `send_shipping_updates` tinyint(1) DEFAULT NULL,
  `bypass_address_validation` tinyint(1) DEFAULT NULL,
  `address_updated_at` timestamp NULL DEFAULT NULL,
  `held_by_user_id` int(11) DEFAULT NULL,
  `sent_to_klaviyo_at` timestamp NULL DEFAULT NULL,
  `updated_by_user_id` int(11) DEFAULT NULL,
  `created_by_user_id` int(11) DEFAULT NULL,
  `subscription` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `orders_txn_id_index` (`txn_id`),
  KEY `orders_customer_id_index` (`customer_id`),
  KEY `orders_payment_status_id_index` (`payment_status_id`),
  KEY `orders_shipment_status_id_index` (`shipment_status_id`),
  KEY `orders_order_status_id_index` (`order_status_id`),
  KEY `orders_agent_id_index` (`agent_id`),
  KEY `orders_store_id_index` (`store_id`),
  KEY `orders_payment_date_index` (`payment_date`),
  KEY `orders_shipping_method_index` (`shipping_method`),
  KEY `orders_shipping_index` (`shipping`),
  KEY `orders_exchange_rate_index` (`exchange_rate`),
  KEY `orders_mc_currency_index` (`mc_currency`),
  KEY `orders_mc_fee_index` (`mc_fee`),
  KEY `orders_mc_gross_index` (`mc_gross`),
  KEY `orders_mc_handling_index` (`mc_handling`),
  KEY `orders_mc_shipping_index` (`mc_shipping`),
  KEY `orders_external_order_id_index` (`external_order_id`) USING BTREE,
  KEY `orders_whs_order_id_index` (`whs_order_id`) USING BTREE,
  KEY `orders_fulfillment_status_id_index` (`fulfillment_status_id`) USING BTREE,
  KEY `orders_parent_order_id_index` (`parent_order_id`) USING BTREE,
  KEY `orders_custom_index` (`custom`) USING BTREE,
  KEY `orders_address_name_index` (`address_name`) USING BTREE,
  KEY `orders_address_email_index` (`address_email`) USING BTREE,
  KEY `orders_address_company_index` (`address_company`) USING BTREE,
  KEY `orders_address_city_index` (`address_city`) USING BTREE,
  KEY `orders_address_state_index` (`address_state`) USING BTREE,
  KEY `orders_address_zip_index` (`address_zip`) USING BTREE,
  KEY `orders_address_country_code_index` (`address_country_code`) USING BTREE,
  KEY `orders_fulfillment_provider_id_index` (`fulfillment_provider_id`) USING BTREE,
  KEY `orders_fulfillment_provider_order_id_index` (`fulfillment_provider_order_id`) USING BTREE,
  KEY `orders_confirmed_at_index` (`confirmed_at`) USING BTREE,
  KEY `orders_agentupdated_at_index` (`agentupdated_at`) USING BTREE,
  KEY `address_id` (`address_id`),
  KEY `payment_profile_id` (`payment_profile_id`),
  KEY `shipping_service_id` (`shipping_service_id`),
  KEY `subscription_group_id` (`subscription_group_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1950715 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `order_items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL,
  `parent_id` int(10) unsigned DEFAULT NULL,
  `product_variant_id` int(11) NOT NULL,
  `subscription_plan_id` int(11) DEFAULT NULL,
  `subscription_id` int(11) DEFAULT NULL,
  `created_by_user_id` int(11) DEFAULT NULL,
  `updated_by_user_id` int(11) DEFAULT NULL,
  `item_name` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `item_number` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `quantity` varchar(127) COLLATE utf8_unicode_ci DEFAULT NULL,
  `type` enum('default','post_purchase','subscription','free','fbt') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'default',
  `unit_price` decimal(9,2) DEFAULT NULL,
  `mc_gross` decimal(9,2) DEFAULT NULL,
  `mc_handling` decimal(9,2) DEFAULT NULL,
  `mc_shipping` decimal(9,2) DEFAULT NULL,
  `tax` decimal(9,2) DEFAULT NULL,
  `free_item` tinyint(4) DEFAULT NULL,
  `replaced_item_id` int(11) DEFAULT NULL,
  `replacement_item` tinyint(4) DEFAULT NULL,
  `athlete_item` tinyint(4) DEFAULT NULL,
  `agent_request` tinyint(4) DEFAULT NULL,
  `care_package` tinyint(4) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `order_items_order_id_index` (`order_id`),
  KEY `order_items_product_variant_id_index` (`product_variant_id`),
  KEY `order_items_item_name_index` (`item_name`),
  KEY `order_items_item_number_index` (`item_number`),
  KEY `order_items_quantity_index` (`quantity`),
  KEY `order_items_mc_gross_index` (`mc_gross`),
  KEY `order_items_mc_handling_index` (`mc_handling`),
  KEY `order_items_mc_shipping_index` (`mc_shipping`),
  KEY `order_items_tax_index` (`tax`),
  KEY `order_items_agent_request_index` (`agent_request`),
  KEY `order_items_care_package_index` (`care_package`),
  KEY `order_items_athlete_item_index` (`athlete_item`),
  KEY `order_items_free_item_index` (`free_item`),
  KEY `order_items_replacement_item_index` (`replacement_item`),
  KEY `parent_id` (`parent_id`),
  KEY `deleted_at` (`deleted_at`),
  KEY `subscription_id` (`subscription_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6675238 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

这是解释表。

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ALL 841782
2 DERIVED o1_order_items ref order_items_order_id_index,order_items_product_variant_id_index order_items_product_variant_id_index 4 const 841782 Using temporary; Using filesort
2 DERIVED o1 eq_ref PRIMARY,orders_customer_id_index,orders_store_id_index PRIMARY 4 shop.o1_order_items.order_id 1 Using where
2 DERIVED customers eq_ref PRIMARY,customers_address_city_index,customers_address_country_index,customers_address_country_code_index,customers_address_state_index,customers_address_zip_index,customers_first_name_index,customers_last_name_index,customers_payer_email_index,customers_residence_country_index,customers_contact_phone_index,customers_payer_business_name_index,customers_address_street_index,customers_address_name_index,deleted_at,promotion_opt_in,type,first_order_id,sanitized_phone,sanitized_phone_last_10 PRIMARY 4 shop.o1.customer_id 1 Using where
2 DERIVED o2 ref orders_customer_id_index,orders_store_id_index,orders_parent_order_id_index orders_customer_id_index 4 shop.customers.id 1 Using where
2 DERIVED o3 ref orders_customer_id_index,orders_store_id_index,orders_parent_order_id_index orders_customer_id_index 4 shop.customers.id 1 Using where
2 DERIVED o4 ref orders_customer_id_index,orders_store_id_index,orders_parent_order_id_index orders_customer_id_index 4 shop.customers.id 1 Using where
2 DERIVED o5 ref orders_customer_id_index,orders_store_id_index,orders_parent_order_id_index orders_customer_id_index 4 shop.customers.id 1 Using where
2 DERIVED o6 ref orders_customer_id_index,orders_store_id_index,orders_parent_order_id_index orders_customer_id_index 4 shop.customers.id 1 Using where

【问题讨论】:

  • 基本设计一开始似乎有缺陷,但基本上你的问题缺少很多信息,如创建表、示例数据和所需结果,
  • 如果它更小且可重现就更好了。我觉得您应该保持数据标准化并在窗口内使用滞后。例如timestampdiff(DAY, purchased_at, LAG(purchased_at) OVER (PARTITION BY store_id, parent_order_id, customer_id ORDER BY purchased_at)) as timediff
  • @YogiPatel 请将您查询的 EXPLAIN 输出添加到您的问题中(作为表格而不是图像 - meta.stackoverflow.com/questions/277716)。此外,为每个表添加 SHOW CREATE TABLE tbl_nameSHOW INDEX FROM tbl_name 也会有所帮助。对于您当前查询的性能不佳,我有一个解释,并建议您以另一种方式获得您想要的结果。
  • @YogiPatel 感谢您为您的问题添加了一些详细信息。希望权力将很快重新提出您的问题。您应该检查您的索引策略,因为您有大量索引,其中一些不太可能使用。
  • 这个问题正在meta讨论。

标签: mysql sql


【解决方案1】:

您当前的查询结构无法正常工作!当您有 customers.total_orders = 1 时,您的查询将返回,因为没有一个左连接返回一个集合。 例如,一位客户有 10 个订单,但只有一个包含所需产品。第一个三个表返回 1 行,第一个 LEFT JOIN 返回 9 行,第二个 8 行,第三个 7 行,第四个 6 行和第五个 5 行。这是 1 个客户的一组 9x8x7x6x5=15,120(在应用 GROUP BY 之前)。如果客户下了 20 个订单,则为 1,395,360 行。向 total_orders 添加索引不会解决此问题。

在你问的问题中 -

如果客户订购了 X 产品,他们的生命周期价值是多少

所以解决方案是找到所有已订购product X 的客户,然后重新加入订单以找到他们的生命周期价值 -

SELECT
    c1.*,
    COUNT(o.id) AS num_orders,
    SUM(o.mc_gross) AS orders_total,
    MIN(o.purchased_at) AS first_order,
    MAX(o.purchased_at) AS last_order,
    IF(COUNT(*) = 1, 0, ROUND(TIMESTAMPDIFF(DAY, MIN(o.purchased_at), MAX(o.purchased_at)) / (COUNT(o.id) - 1))) AS avg_between_orders
FROM (
    SELECT customers.id, customers.name
    FROM customers
    INNER JOIN orders o
        ON o.customer_id = customers.id AND o.store_id = 10
    INNER JOIN order_items oi
        ON oi.order_id = o.id AND oi.product_variant_id = 1
    # THE INNER JOIN to orders renders this WHERE clause redundant
    # WHERE customers.total_orders >= 1
    WHERE customers.created_at >= CURDATE() - INTERVAL 365 DAY
    GROUP BY customers.id
) AS c1
INNER JOIN orders o ON c1.id = o.customer_id
GROUP BY c1.id

我的小型测试数据集(3 个客户、13 个订单和 3 个 order_items)显示为您的查询检查了 36,134 行,但我的查询检查了 16 行。

【讨论】:

  • 听起来是个好的开始。也许它需要HAVING num_orders <= 6
  • @RickJames 是的,你可能是对的。我假设这个限制是由于 OP 的方法造成的。
【解决方案2】:
  • 从查找第 1 次、第 2 次、第 3 次、第 4 次、第 5 次和第 6 次遇到“客户以及每次订单的平均值”的客户 ID 开始。这里的目标是完成查找这些 ID 所需的最少工作.

  • 获取订单数 (1-6) 以及最小和最大日期(见下文)。稍后我们会将它们“透视”到多个列中(见下文)。

  • 之后,加入其他(或相同)表以获取其他所需的列。这里的希望是上一步大大减少了 id 的数量,以至于这一步不必做太多的工作。

  • 最终“枢轴”将行变成列。多组是这样处理的

    count(o3_id) as "Total-o3",
    avg(o3_total) as "Order Value-o3",
    avg(TimeDiff_o3) as "Avg-o3-o4(Days)",
    
  • 计算 nnichols 之间的平均时间 -- (max-min)/count。不需要 LAG(),这可能会非常昂贵。

  • 这可能涉及嵌套到 2 或 3 深度的 Select,并且会有一些 JOINs,但可能没有 LEFT JOINs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多