Opened 5 months ago
Last modified 5 months ago
#62931 new defect (bug)
Inconsistency When Querying and Sorting by meta_key with Multiple Values
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 6.7.1 |
Component: | Query | Keywords: | dev-feedback 2nd-opinion |
Focuses: | Cc: |
Description
Description:
I've encountered an issue with a SQL query generated by WordPress when sorting posts by a meta_key value. When I copied the exact same query into phpMyAdmin, it resulted in an error, whereas it worked fine within WordPress. Upon further investigation, I realized that this discrepancy occurs because WordPress disables the SQL mode "ONLY_FULL_GROUP_BY" by default.
The error itself is caused when sorting posts based on the "meta_key" column, when some posts have multiple values for the same meta_key. This leads to inconsistent sorting results and, with "ONLY_FULL_GROUP_BY" enabled, a SQL error.
Example Scenario:
Consider a custom post type "biography," where each post has a meta_key "nationality." Some biographies may have multiple nationalities (e.g., "Algeria" and "Zimbabwe"). When sorting biographies by nationality, the sorting behavior for posts with multiple values is unpredictable—it may randomly appear at start or at end.
Current Query Generated by WordPress:
SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 [...] GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value
Suggested Fix:
To resolve this issue, an aggregation function such as MIN()
should be used:
SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 [...] GROUP BY wp_posts.ID ORDER BY MIN(wp_postmeta.meta_value)
Related Ticket
https://core.trac.wordpress.org/ticket/54669
Change History (2)
#1
follow-up:
↓ 2
@
5 months ago
- Component changed from General to Query
- Keywords dev-feedback 2nd-opinion added
#2
in reply to:
↑ 1
@
5 months ago
Replying to mayanktripathi32:
MIN function might negatively affect performance of query here, MySQL needs to compare all values for each post to determine the minimum which can cause slow downs if too many rows are present.
If performance is the issue, lets consider ANY_VALUE()
instead of MIN()
. That wouldn't resolve the problem of inconsistency but at least would stick better with MYSQL standards.
MIN function might negatively affect performance of query here, MySQL needs to compare all values for each post to determine the minimum which can cause slow downs if too many rows are present.