orderby is the argument passed to
WP_Query to tell it what column to sort on when it is creating the
ORDER BY clause for its generated SQL. The default value for
The default sort order for a column in MySQL is
ASC (ascending), with smallest values first. For the reverse,
DESC is used. You can sort on multiple columns, and each column can have its own sort order.
The default value for the
order argument inside
DESC. ~23% of the internet automatically queries posts in reverse chronological order because of this.
order can only be one of 2 values:
orderby accepts a string, representing a column on which to sort:
$q = new WP_Query( array( 'orderby' => 'post_title' ) ); // or an alias $q = new WP_Query( array( 'orderby' => 'title' ) );
Both will produce an
ORDER BY clause like:
ORDER BY post_title DESC
orderby will also parse a space-delimited set of columns:
$q = new WP_Query( array( 'orderby' => 'title author' ) );
Prior to 4.0, there was a problem: the value for
order would only be applied to the last value that you passed in that space-delimited list, producing an ORDER BY clause like:
ORDER BY post_title, post_author DESC
Remember that the default sort order for a column in MySQL is
ASC, so queries like that can get weird real fast and produce unexpected/unpredictable results. If no value is passed for order for a column in the generated SQL, the column will be sorted in
ASC order. This was not so clear to all developers. #26042 was a joy to debug.
In 4.0, when you pass a space-delimited set of values, your sole value for
order will be applied to all of your values that are parsed for
orderby. This was fixed in .
So that’s pretty good, but it doesn’t allow you granular control over the sort order for each column. The syntax doesn’t allow itself much room for extending.
In 4.0, you can now pass an array to
WP_Query as the value for
orderby. The syntax looks like:
$q = new WP_Query( array( 'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' ) ) );
This allows you to control the generation of the
ORDER BY clause with more specificity:
ORDER BY post_title DESC, menu_order ASC
Pre-4.0, you would have had to use some gnarly filters on the SQL statement or a specific clause. No bueno.
To see the internals, check out the new
protected methods in