SQL: суммирование по операторам CASE, возвращающее неверный результат - PullRequest
0 голосов
/ 03 сентября 2018

Прошло много лет с тех пор, как я написал сложные операторы SQL. Я работаю в WordPress / WooCommerce и пытаюсь суммировать заказы против каждого клиента.

Когда я начал тестирование с этим оператором SQL, чтобы просто получить список заказов с включенной информацией о клиенте, он работает:

SELECT wp_users.ID as userID,
       wp_posts.post_date,
       wp_posts.post_type,
       wp_users.user_email,
       MAX(CASE WHEN wp_usermeta.meta_key = 'billing_first_name' THEN wp_usermeta.meta_value END) as firstName,
       MAX(CASE WHEN wp_usermeta.meta_key = 'billing_last_name' THEN wp_usermeta.meta_value END) as lastName,
       MAX(CASE WHEN wp_woocommerce_order_itemmeta.meta_key = '_line_total' THEN wp_woocommerce_order_itemmeta.meta_value END) as orderTotal

FROM wp_posts
  INNER JOIN wp_postmeta
     ON wp_postmeta.post_id = wp_posts.ID
  INNER JOIN wp_users
     ON wp_postmeta.meta_key = '_customer_user'
     AND wp_users.ID = wp_postmeta.meta_value
  INNER JOIN wp_usermeta
     ON wp_usermeta.user_id = wp_users.ID
  INNER JOIN wp_woocommerce_order_items
     ON wp_woocommerce_order_items.order_id = wp_posts.ID
  INNER JOIN wp_woocommerce_order_itemmeta
     ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
WHERE wp_posts.post_type IN ('shop_order','shop_subscription') 
GROUP BY wp_posts.ID

Результат показан на первом изображении здесь: https://imgur.com/a/mZs9Iej

И если я суммирую эти результаты в excel (на данный момент есть только 1 тестовый пользователь), то для этого пользователя будет показано 4281 $.

Если я затем попытаюсь использовать SUM в операторе SQL для каждого пользователя, как здесь (только две строки изменены, последний MAX изменен на SUM, а GROUP BY изменен на wp_users.ID):

SELECT wp_users.ID as userID,
       wp_posts.post_date,
       wp_posts.post_type,
       wp_users.user_email,
       MAX(CASE WHEN wp_usermeta.meta_key = 'billing_first_name' THEN wp_usermeta.meta_value END) as firstName,
       MAX(CASE WHEN wp_usermeta.meta_key = 'billing_last_name' THEN wp_usermeta.meta_value END) as lastName,
       SUM(CASE WHEN wp_woocommerce_order_itemmeta.meta_key = '_line_total' THEN wp_woocommerce_order_itemmeta.meta_value END) as userTotal

FROM wp_posts
  INNER JOIN wp_postmeta
     ON wp_postmeta.post_id = wp_posts.ID
  INNER JOIN wp_users
     ON wp_postmeta.meta_key = '_customer_user'
     AND wp_users.ID = wp_postmeta.meta_value
  INNER JOIN wp_usermeta
     ON wp_usermeta.user_id = wp_users.ID
  INNER JOIN wp_woocommerce_order_items
     ON wp_woocommerce_order_items.order_id = wp_posts.ID
  INNER JOIN wp_woocommerce_order_itemmeta
     ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
WHERE wp_posts.post_type IN ('shop_order','shop_subscription') 
GROUP BY wp_users.ID

Возвращает слишком большую сумму в 340 тыс. Долларов вместо 4 тыс. Долларов, как показано на втором рисунке: https://imgur.com/a/mZs9Iej

Может кто-нибудь заметить ошибку, которую я сделал? Любая помощь приветствуется!

1 Ответ

0 голосов
/ 03 сентября 2018

Попробуйте это

SELECT users.ID as userID,
       posts.post_date,
       posts.post_type,
       users.user_email,
       fname.meta_value as firstName,
       lname.meta_value as lastName,
       SUM(itemmeta.meta_value) as userTotal
FROM wp_posts posts
  INNER JOIN wp_postmeta postmeta
     ON postmeta.post_id = posts.ID
     AND postmeta.meta_key = '_customer_user'
  INNER JOIN wp_users users
     ON users.ID = postmeta.meta_value
  INNER JOIN wp_woocommerce_order_items items
     ON items.order_id = posts.ID
  INNER JOIN wp_woocommerce_order_itemmeta itemmeta
     ON itemmeta.order_item_id = items.order_item_id
     AND itemmeta.meta_key = '_line_total'
  LEFT JOIN wp_usermeta fname
     ON fname.user_id = users.ID 
     AND fname.meta_key = 'billing_first_name'
  LEFT JOIN wp_usermeta lname
     ON lname.user_id = users.ID 
     AND lname.meta_key = 'billing_last_name'
WHERE posts.post_type IN ('shop_order','shop_subscription') 
GROUP BY users.ID

Я ввел псевдонимы для таблиц и заменил ваши конструкции case левыми объединениями.

Кажется, вам нужно указать meta_keys в качестве условий, потому что в противном случае вы будете объединять строки, которые не будут совпадать с meta_key. Это, в свою очередь, умножит соединенные строки на wp_woocommerce_order_itemmeta и, следовательно, на атрибуты, которые вы хотите суммировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...