Я создаю SQL-запрос, где я хочу отображать полные имена и электронные письма клиентов, которые приобрели загружаемый продукт из магазина woocommerce. Я ищу что-то вроде этого:Wordpress SQL запрашивает имя пользователя и фамилию для продукта X?
user_id first_name last_name user_email order
---------------------------------------------------------
1 Peter Jones [email protected] Doc_1
В приведенной выше таблице, Doc_1 означает название продукта, в этом случае клиенту user_id = 1 можно скачать Doc_1. Для WordPress пользователей, вы знаете, что таблица wp_usermeta
содержит всю информацию о пользователе, и выглядит следующим образом:
umeta_id user_id meta_key meta_value
---------------------------------------------
1 1 nickname petjon123
2 1 first_name Peter
3 1 last_name Jones
... ... ... ...
Этот список идет вниз, содержащий более meta_value[s]
включая электронную почту и т.д. Все было бы гораздо проще, если в meta_key[s]
были бы заголовки таблиц, показывающие first_name
и last_name
рядом друг с другом, а не сверху друг с другом. Я зашел так далеко, где мой запрос показывает first_name
, но у меня возникли проблемы с получением last_name
. Моя SQL-запрос выглядит следующим образом:
SELECT
wp_usermeta.user_id,
wp_usermeta.meta_value AS 'first_name',
Wp_woocommerce_downloadable_product_permissions_1.user_email AS 'email',
Wp_woocommerce_order_items_1.order_item_name AS 'order'
FROM Wp_woocommerce_order_items
INNER JOIN Wp_woocommerce_downloadable_product_permissions
ON Wp_woocommerce_order_items.order_id = Wp_woocommerce_downloadable_product_permissions.order_id,
(Wp_woocommerce_order_items AS Wp_woocommerce_order_items_1
INNER JOIN Wp_woocommerce_downloadable_product_permissions AS Wp_woocommerce_downloadable_product_permissions_1
ON Wp_woocommerce_order_items_1.order_id = Wp_woocommerce_downloadable_product_permissions_1.order_id)
INNER JOIN wp_usermeta
ON Wp_woocommerce_downloadable_product_permissions_1.user_id = wp_usermeta.user_id
GROUP BY wp_usermeta.user_id,
wp_usermeta.meta_value,
Wp_woocommerce_downloadable_product_permissions_1.user_email,
Wp_woocommerce_order_items_1.order_item_name,
Wp_woocommerce_order_items_1.order_item_type,
wp_usermeta.meta_key
HAVING (((Wp_woocommerce_order_items_1.order_item_type) = 'line_item')
AND ((wp_usermeta.meta_key) = 'first_name'));
Дай мне этот результат:
user_id first_name user_email order
--------------------------------------------
1 Peter [email protected] Doc_1
Я проверил эти значения вручную, и они правильны, однако, я должен сказать, что если я не GROUP результаты, я получаю в 1000 раз больше результатов, поэтому GROUPING данные упрощают результаты, в основном удаляя дубликаты, которые явно чрезмерны. Я сомневаюсь, что этот запрос эффективен, учитывая, что время выполнения до появления результатов равно +/- 20368.14 мс и поэтому очень открыто для любых предложений по улучшению этого кода. Сказав это, я подумал, что мне нужно было сделать еще один запрос, чтобы получить last_name
, сделав это NESTED QUERY. Если я открою таблицы в MS Access, создайте let say Query1, который является запросом выше, и присоедините Query1 с таблицей. Я получаю результаты, которые я хочу. SQL-код для этого заключается в следующем:
SELECT
Query1.user_id,
Query1.first_name,
wp_usermeta.meta_value AS 'last_name',
Query1.user_email,
Query1.order_item_name
FROM wp_usermeta
INNER JOIN Query1
ON wp_usermeta.user_id = Query1.user_id
WHERE (((wp_usermeta.meta_value) <> '')
AND ((wp_usermeta.meta_key) = 'last_name'));
Я попытался подставляя Query1 для второго запроса, используя круглые скобки, заключив код с Query1, и это не сработало. Я получаю эту ошибку:
У вас возникла ошибка в синтаксисе SQL; проверьте руководство, которое соответствует версии сервера MySQL для правильного синтаксиса использовать вблизи».user_id, (SELECT wp_usermeta.user_id, wp_usermeta.meta_value AS„первый“в строке 22
Кто-нибудь знает, как это сделать? Благодаря!!
UPDATE
Согласно ответу, @Hogan я пришел с этим:
SELECT
first.user_id,
first.meta_value AS 'first_name',
last.meta_value AS 'last_name',
Wp_woocommerce_downloadable_product_permissions_1.user_email,
Wp_woocommerce_order_items_1.order_item_name
FROM Wp_woocommerce_order_items
INNER JOIN Wp_woocommerce_downloadable_product_permissions
ON Wp_woocommerce_order_items.order_id = Wp_woocommerce_downloadable_product_permissions.order_id,
wp_usermeta AS last
INNER JOIN ((Wp_woocommerce_order_items AS Wp_woocommerce_order_items_1
INNER JOIN Wp_woocommerce_downloadable_product_permissions AS Wp_woocommerce_downloadable_product_permissions_1
ON Wp_woocommerce_order_items_1.order_id = Wp_woocommerce_downloadable_product_permissions_1.order_id)
INNER JOIN wp_usermeta AS first
ON Wp_woocommerce_downloadable_product_permissions_1.user_id = first.user_id)
ON last.user_id = Wp_woocommerce_downloadable_product_permissions_1.user_id
GROUP BY first.user_id,
first.meta_value,
last.meta_value,
Wp_woocommerce_downloadable_product_permissions_1.user_email,
Wp_woocommerce_order_items_1.order_item_name,
Wp_woocommerce_order_items_1.order_item_type,
first.meta_key,
last.meta_key
HAVING (((Wp_woocommerce_order_items_1.order_item_type) = 'line_item')
AND ((first.meta_key) = 'first_name')
AND ((last.meta_key) = 'last_name'));
Который отлично работает в MS Access, но в SQL нет. Я получаю эту ошибку:
Неизвестный столбец 'first.meta_key' в 'имеющей п'
Почему?
Я также должен упомянуть, что, когда я добавить meta_key[s]
к SELECT
, как это:
SELECT
first.user_id,
first.meta_value AS 'first_name',
last.meta_value AS 'last_name',
Wp_woocommerce_downloadable_product_permissions_1.user_email,
Wp_woocommerce_order_items_1.order_item_name,
first.meta_key,
last.meta_key
Я по крайней мере не получаю сообщение об ошибке, то запрос выполняется, но она идет и об увеличении моего использования процессора что я работаю над локальным хостом.
РЕШЕНИЕ
SELECT DISTINCT
сделал трюк. No GROUPING. Результаты запроса отображаются в 127,76 мс. Это мой запрос:
SELECT DISTINCT
first.user_id AS 'id',
first.meta_value AS 'first_name',
last.meta_value AS 'last_name',
Wp_woocommerce_downloadable_product_permissions_1.user_email AS 'email',
Wp_woocommerce_order_items_1.order_item_name AS 'order'
FROM Wp_woocommerce_order_items
INNER JOIN Wp_woocommerce_downloadable_product_permissions
ON Wp_woocommerce_order_items.order_id = Wp_woocommerce_downloadable_product_permissions.order_id,
((Wp_woocommerce_order_items AS Wp_woocommerce_order_items_1
INNER JOIN Wp_woocommerce_downloadable_product_permissions AS Wp_woocommerce_downloadable_product_permissions_1
ON Wp_woocommerce_order_items_1.order_id = Wp_woocommerce_downloadable_product_permissions_1.order_id)
INNER JOIN wp_usermeta AS first
ON Wp_woocommerce_downloadable_product_permissions_1.user_id = first.user_id)
INNER JOIN wp_usermeta AS last
ON Wp_woocommerce_downloadable_product_permissions_1.user_id = last.user_id
WHERE (((first.meta_key) = 'first_name')
AND ((last.meta_key) = 'last_name')
AND ((Wp_woocommerce_order_items_1.order_item_type) = 'line_item'));
Как указано @Hogan, просто добавить таблицу wp_usermeta
снова с другим псевдонимом, и сделать INNER JOIN
.
Как и в сторону, ваш запрос предполагает, что все мета ключи заполняются. Это может быть справедливо для таких вещей, как имя и фамилия, но может быть не так для других мета-ключей - в этом случае INNER JOIN будет опускать этого клиента, а вместо этого следует использовать OUTER JOIN. – Strawberry
Эти не похожи на мои запросы. Я никогда не ставил 'first.meta_key = 'first_name'' в предложение' HAVING' или в 'WHERE' или между этими круглыми скобками. Серьезно избавиться от всех круглых скобок, это не алгебра, они не имеют значения. Поместите их в соединение, как я, это сделает ваш запрос быстрее и понятнее. – Hogan
@ Хоган Ок. Я сделаю так. Спасибо за помощь! –