Make WordPress Core

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: maximeschoeni's profile maximeschoeni 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: @mayanktripathi32
5 months ago

  • Component changed from General to Query
  • Keywords dev-feedback 2nd-opinion added
ORDER BY MIN(wp_postmeta.meta_value)

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.

#2 in reply to: ↑ 1 @maximeschoeni
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.

Note: See TracTickets for help on using tickets.