totally new to MySQL and am trying to extract some data - I was expecting this to be a relatively simple task but I didnt realise that the "format" of the data extract wouldnt have the column headings i expected. I've done some research and think I'm very close to the answer, provided here:
SQL - How to transpose?
However, when writing my query I'm getting a syntax error.
So here is the code I've applied (using a little common sense to work out my specific values, although may have totally missed the mark!)
SELECT wp_usermeta.User_ID
MAX(CASE WHEN wp_usermeta.meta_key = 'nickname' THEN wp_usermeta.meta_value ELSE NULL END) AS 'nickname',
MAX(CASE WHEN wp_usermeta.meta_key = 'sex' THEN wp_usermeta.meta_value ELSE NULL END) AS 'sex'
FROM wp_usermeta
GROUP BY wp_usermeta.User_ID
The error I'm getting is a #1064 advising to check the syntax on line 2 near 'MAX(CASE WHEN wp_usermeta.meta_key = 'nickname' THEN wp_usermeta.meta_value ELSE'
I'm sure this is a simple syntax error but i can't work it out!
Many thanks,
Stuart
In wordpress you can use WPDB class to retrieve results from raw query
global $wpdb;
$results=$wpdb->get_results( "SELECT wp_usermeta.User_ID,
MAX(CASE WHEN wp_usermeta.meta_key = 'nickname' THEN wp_usermeta.meta_value ELSE NULL END) AS 'nickname',
MAX(CASE WHEN wp_usermeta.meta_key = 'sex' THEN wp_usermeta.meta_value ELSE NULL END) AS 'sex'
FROM wp_usermeta
GROUP BY wp_usermeta.User_ID" );
if(!empty($results)){
foreach($results as $r){
echo $r->User_ID ."<br />";
echo $r->nickname ."<br />";
echo $r->sex ."<br />";
}
}
Wordpress Class WPDB
If you write your SELECTs this way, then that problem can never occur...
SELECT m.User_ID
, MAX(CASE WHEN m.meta_key = 'nickname' THEN m.meta_value END) nickname
, MAX(CASE WHEN m.meta_key = 'sex' THEN m.meta_value END) sex
FROM wp_usermeta m
GROUP
BY m.User_ID
Related
I want to limit each user to register only one order per day.
To do this, I need to check each user's order before registering whether this user has any 'wp-processing' order or not?
I wrote below MySQL query in PHP, but it doesn't work.
I printed value of '$sql_count_from_status' and try it in phpmyadmin, SQL tab to find the error.
Value of the variable was:
SELECT count(ID) FROM wp_posts p LEFT JOIN wp_postmeta m ON p.ID=m.post_id WHERE p.post_status LIKE 'wc-processing' AND p.post_type LIKE 'shop_order' AND m.meta_key LIKE '_customer_user' AND m.meta_value LIKE '100577';
and showed me zero in phpmyadmin as result. Now I know the query has problem, because I had 'processing order' for user 100577.
function get_orders_count_from_status( $status , $this_user_id){
global $wpdb;
// We add 'wc-' prefix when is missing from order staus
$status = 'wc-' . str_replace('wc-', '', $status);
$sql_count_from_status = "
SELECT count(ID) FROM {$wpdb->prefix}posts p
LEFT JOIN {$wpdb->prefix}postmeta m
ON p.ID=m.post_id
WHERE p.post_status LIKE '$status' AND p.post_type LIKE 'shop_order'
AND m.meta_key LIKE '_customer_user'
AND m.meta_value LIKE '".$this_user_id."';";
return $wpdb->get_var($sql_count_from_status);
}
Here's an example of a plausible query (although counting on a LEFT JOIN is a bit strange):
SELECT count(*)
FROM {$wpdb->prefix}posts p
LEFT
JOIN {$wpdb->prefix}postmeta m
ON m.post_id = p.ID
AND m.meta_key = '_customer_user'
AND m.meta_value = :this_user_id
WHERE p.post_status LIKE :status
AND p.post_type = 'shop_order'
so I have this SQL query:
SELECT
p.ID
FROM
`cdlr_posts` p,
cdlr_postmeta pm
WHERE
pm.post_id=p.ID AND
`post_type` = 'shop_order' AND
pm.meta_key = '_statusCDLR' AND
pm.meta_value <> 1
group by
p.ID
What I need is to show all the IDS if they match with those conditions, but I will also like to show the ones that do not contain the "_statusCDLR" meta_key I tried something like this with no luck:
WHERE
pm.post_id=p.ID AND
`post_type` = 'shop_order' AND
(pm.meta_key = '_statusCDLR' AND pm.meta_value <> 1 OR pm.meta_key <> '_statusCDLR')
group by
Any help will be appreciated to achieve what I need.
I understand that your requirement is to select the id of posts that :
either have a corresponding record in cdlr_post_meta with meta_key = 'statusCDLR' and meta_value <> 1
or do not have a record cdlr_post_meta with meta_key = 'statusCDLR'
A strategy to achieve this is to use a LEFT JOIN to search for a record in cdlr_post_meta with meta_key = 'statusCDLR', and then implement the rest of the logic in the WHERE clause (if there is no corresponding record, the columns of pm are all NULL).
SELECT p.ID
FROM cdlr_posts p
LEFT JOIN cdlr_postmeta pm
ON pm.post_id = p.ID AND pm.meta_key = '_statusCDLR'
WHERE
p.post_type = 'shop_order'
AND ( pm.post_id IS NULL OR pm.meta_value <> 1 )
GROUP BY p.ID
PS - General remarks regarding your sql :
When mixing ORs and ANDs, you need to surround the test expressions within parentheses to avoid running into prescedence issues (AND has higher precedence than OR).
you should use explicit JOINs instead of implicit ones.
I am working on a query to flatten some wp_postsmeta data in a WordPress database and need to set a specific value on various meta_values. I have a key of category and various category values, for each value, I want to set a column named color with a named color for our brand palette
select post_title as title,
MAX(CASE WHEN meta_key='corporate_calendar_category' THEN meta_value END) as 'category',
MAX(CASE WHEN meta_key = 'corporate_calendar_subcategory' THEN meta_value END) as 'subcategory',
// Do I need to include a nested CASE WHEN?
MAX(CASE WHEN meta_key = 'corporate_calendar_subcategory' and meta_value = 'Marketing' THEN 'blueLagoon' END) as 'color',
MAX(CASE WHEN meta_key = 'corporate_calendar_presenter' THEN meta_value END) as 'presenter',
MAX(CASE WHEN meta_key = 'corporate_calendar_date' THEN meta_value END) as 'start_date',
MAX(CASE WHEN meta_key = 'corporate_calendar_time' THEN meta_value END) as 'start_time',
MAX(CASE WHEN meta_key = 'corporate_calendar_duration' THEN meta_value END) as 'duration',
MAX(CASE WHEN meta_key = 'corporate_calendar_registration_link' THEN meta_value END) as 'registration_link',
MAX(CASE WHEN meta_key = 'corporate_calendar_description' THEN meta_value END) as 'description',
MAX(CASE WHEN meta_key = 'corporate_calendar_image_path' THEN meta_value END) as 'image_path'
FROM wp_posts p
JOIN wp_postmeta m ON p.id = m.post_id
where p.post_type = 'calendar-event'
and p.post_status = 'publish'
GROUP BY p.id
corporate_calendar_subcategory has many values, Marketing, HR, Company Holiday, etc, and for each subcategory I want each row to have a specific color.
title category subcategory color presenter start_date etc.
Example Training Marketing blueLagoon someone 08/29/2018
Labor Day Reminder Company Holiday camelot 09/03/2018
etc
etc
Is the best way to achieve this to use a nested CASE WHEN against the meta_value? Or is there a better way?
I also tried including an if statement (below) but that duplicated each row.
if(meta_key = 'corporate_calendar_subcategory',
CASE
WHEN meta_value = 'Marketing' THEn 'blueLagoon'
WHEN meta_value = 'Company Holiday' THEN 'camelot'
END,
'') as color,
Yes, the nested CASE statement would be the right way to go if you know all the categories and colors beforehand. If the category-colors are in another table, you can do either a subselect or a JOIN instead.
Here's an example with nested case:
max(case when meta_key = 'corporate_calendar_subcategory' then
case meta_value
when 'Marketing' then 'blue'
when 'Sales' then 'yellow
when 'Development' then 'red'
end
end)
I'm not sure how to word what I need so here goes... This is part of a search that allows a type and a state to be selected. I need to be able to run this query to match the type and state from the same mysql column which is meta_value. The problem is it's returning every type for the selected state in the result.
Example: I pick Drag Strip for the type and South Carolina for the state I only want to see the Drag Strip's in South Carolina and not the other types (oval, road course, etc) that are in South Carolina or any other state.
Below is what I have right now that isn't working, I'm not really sure where to go with it to get the result I need.
SELECT dmp_postmeta.meta_value, dmp_posts.post_title, dmp_posts.post_type,
dmp_posts.post_status, dmp_posts.id
FROM dmp_postmeta, dmp_posts
WHERE dmp_postmeta.meta_value IN ('South Carolina','Drag Strip')
AND dmp_posts.post_type='my_custom_tracks'
AND dmp_posts.post_status='publish'
GROUP BY dmp_postmeta.post_id ORDER BY dmp_posts.post_title
meta_key meta_value
Track_Type Drag Strip
Track_Type Oval
Track_Location South Carolina
Track_Location Texas
******Solved******
"SELECT p.ID as id, p.post_title, p.post_type, p.post_status as post_status, MAX(CASE WHEN pm1.meta_value='".$track_type."' then pm1.meta_value ELSE NULL END) as track_type, MAX(CASE WHEN pm1.meta_value='".$track_state."' then pm1.meta_value ELSE NULL END) as track_state FROM dmp_posts p LEFT JOIN dmp_postmeta pm1 ON ( pm1.post_id = p.ID) WHERE p.post_type='my_custom_tracks' AND p.post_status='publish' GROUP BY p.ID, p.post_title ORDER BY p.post_title"
This is what I finally got to work. Thanks for the help guys.
"SELECT p.ID as id, p.post_title, p.post_type, p.post_status as post_status, MAX(CASE WHEN pm1.meta_value='".$track_type."' then pm1.meta_value ELSE NULL END) as track_type, MAX(CASE WHEN pm1.meta_value='".$track_state."' then pm1.meta_value ELSE NULL END) as track_state FROM dmp_posts p LEFT JOIN dmp_postmeta pm1 ON ( pm1.post_id = p.ID) WHERE p.post_type='my_custom_tracks' AND p.post_status='publish' GROUP BY p.ID, p.post_title ORDER BY p.post_title"
I have a query that looks like this:
SELECT
app.application_id,
j.job_number,
j.job_id,
j.job_title,
j.job_city,
j.job_state,
p.person_id AS candidate_id,
p.first_name,
p.last_name,
app.start_date,
ope1.percent_complete,
MAX(CASE
WHEN r.role_display_name = 'ENG - Recruiter' THEN
(SELECT CASE WHEN COUNT(last_name) = 0 THEN
'Unassigned'
ELSE
COUNT(last_name)
END AS uname
FROM users
JOIN job_roles ON job_roles.user_id = users.user_id
WHERE job_id = j.job_id
AND role_id = r.role_id
)
ELSE '' END) AS role_3
My problem is that COUNT(last_name) will not return 0, because there are no records returned, so there is no value of NULL. All makes sense, however I have tried wrapping it in IFNULL(), ISNULL() and none of them seem to fix this problem. How can I get it to return 0 when there are no records? Do I need another subquery inside the COUNT() aggregate? I would really like to not use another subquery....
If understand correctly what you want you can try to rewrite it this way
SELECT ...
,MAX(CASE WHEN r.role_display_name = 'ENG - Recruiter'
THEN COALESCE(NULLIF(
(
SELECT COUNT(last_name)
FROM users JOIN job_roles
ON job_roles.user_id = users.user_id
WHERE job_id = j.job_id
AND role_id = r.role_id
), 0), 'Unassigned')
ELSE ''
END) as role_3
...