Updated: Comment #3 by dooug
Problem/Motivation
I am trying to sort nodes by the combination of two different date fields. The View can be sorted by one date field, but using two date fields in the sort will sort by one field first, then the other.
I want to achieve this: (Nodes are being sorted by date, no matter if the date is from "date-field 1" or "date-field 2")
- Node 1 (date-field 1: 01. 2012)
- Node 2 (date-field 2: 02. 2012)
- Node 3 (date-field 2: 03. 2012)
- Node 4 (date-field 2: 04. 2012)
- Node 5 (date-field 1: 05. 2012)
- Node 6 (date-field 2: 06. 2012)
- Node 7 (date-field 1: 07. 2012)
- Node 8 (date-field 2: 08. 2012)
- Node 9 (date-field 1: 09. 2012)
By setting up views "sort" panel adding the two date fields will render the following view:
- Node 1 (date-field 1: 01. 2012)
- Node 5 (date-field 1: 05. 2012)
- Node 7 (date-field 1: 07. 2012)
- Node 9 (date-field 1: 09. 2012)
- Node 2 (date-field 2: 02. 2012)
- Node 3 (date-field 2: 03. 2012)
- Node 4 (date-field 2: 04. 2012)
- Node 6 (date-field 2: 06. 2012)
- Node 8 (date-field 2: 08. 2012)
It sorts the date field correctly, but wont combine the date-fields. So the Dates are getting mixed up completely.
There appear to be a handful of requests for this, including but not limited to:
#378694: sort by date, combining fields
http://stackoverflow.com/questions/12578343/drupal-views-multiple-sort-c...
http://stackoverflow.com/questions/11769902/drupal-7-sorting-multiple-co...
http://drupal.stackexchange.com/questions/32679/how-do-i-sort-two-differ...
Proposed resolutions
Summary of possible solutions / work-arounds:
- Combining date fields so there is only one date field to sort by. As necessary, hiding elements that are unnecessary for some field instances. Suggested here: http://skvare.com/blog/sort-multiple-formats-date-fields-views
- Similar to the last but keep the existing separate date fields, then do custom coding to sync/hide the multiple fields on a content type so one field can be used to sort. Suggested here: https://drupal.org/comment/6927200#comment-6927200
- Use either views_php or computed_field to write custom PHP to sort the view. Suggested here: https://drupal.org/comment/4558482#comment-4558482
(likely) Best solution (at the time of writing this):
In a custom module use the hook_views_query_alter() function to alter the sort criteria to use CASE ... WHEN to add a conditional in the orderby condition. A good example is shown here:
/**
* Implements hook_views_query_alter
* @param type $view
* @param type $query
*/
function MODULE_views_query_alter(&$view, &$query) {
if ($view->name == 'views_name' && $view->current_display == 'display_name') {
$query->orderby = array(
array(
'field' => 'CASE WHEN field_data_field_date_publication.field_date_publication_value THEN field_data_field_date_publication.field_date_publication_value ELSE node.created END',
'direction' => 'DESC',
)
);
}
}
Credit goes to eloone here: https://drupal.org/comment/6443200#comment-6443200
Issue fork views-2133879
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
dooug commentedThe issue is more relevant to Views module than the Date module that it was posted to.
Comment #2
dooug commentedUpdated with lots of research on possible solutions & work-arounds.
Also, marked as won't fix because it is possible to solve with views hooks. Though, a contrib module to provide an interface for this would be delightful.
Comment #3
dooug commentedComment #4
dooug commentedfixed typo and issue reference
Comment #5
stephan-mjut commentedDooug: Thanks a lot. This is awesome!
Comment #6
Geijutsuka commentedI'm a little confused about exactly where the two different fields are supposed to be substituted in the code (please forgive my ignorance of PHP). It looks as if the code only accommodates for one field: field_date_publication—I don't understand where the other date field is. If I have two different date fields, say, field_schedule_consistentdates and field_schedule_customdates, how would they be plugged into this equation?
EDIT: Sorry... I just realized the other field was the node creation date.
Comment #7
pauldolphin commentedThank you so much for the AWESOME writeup. Just wanted to include an example of sorting by more than two date fields for anyone else who may be struggling like I was.
I ran into some issues and had to lookup proper syntax for the CASE function. The extra WHEN / THEN statements got me what I needed. Thanks again for the great analysis. I was on the verge of adding an additional universal date-sort field before I stumbled across this.
The example below sorts by ascending dates for the following fields: date_time, date_time_range, date
Comment #8
charly71 commentedIf I want to sort by the first value of a date field with start and end values?
I tried this code but won't work:
(in this case name2 field has two values, start and end)
Comment #9
amogiz commented#7 It worked perfectly for me. Great thanx … i was about to spend days searching …:)
Comment #10
dalemoore commentedFor anyone who has a situation where one of your date fields is in a Field Collection, this worked for me in D7 with Views 3.
In MODULE.module:
In MODULE_views.inc:
Comment #11
dmudie commentedHi,
Hoping someone can help shed some light on this. I have a "public title" field on nodes that site editors can define. My hope is that if there is a value in this field, it will use that as the sort, otherwise I want it to use the node title. Here's my code in query alter. Any help is greatly appreciated!
Comment #12
stephen ollmanRe this solution:
I'm getting errors in the specified view saying that it cannot find the column even when I'm using the table and column name direct from the database.
So in the example about the error I'm getting it:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_data_field_date_publication.field_date_publication_value' in 'order clause'
Comment #13
niallmurphy-ie commented#7 works great! Thanks so much.
Comment #14
maxplus commentedHi,
I used this sandbox to combine two different date fields in my Views sort, works great:
https://www.drupal.org/sandbox/hazah/2285127
Comment #15
antonyanimator commented@maxplus thanks for the link, but I tried the sandbox and it didn't work for me
Comment #16
sensedrive commentedI am not very active in this community, but I faced the same issue and maybe my solution helps someone. It is based on the Search API module and the Search API Combined Fields module and works like charm (for my purposes).
... without any written lines of code.
Comment #17
mrpauldriver commented@sensedrive. Was this approach for Drupal 7 or 8?
I guess it's a similar approach for either, but interested in your experience.
Comment #18
sourabhbhalerao commentedMy problem solved by following 'case when' for orderby in views query alter...I wanted to sort views list by custom table weight and node changed date.
Thanks
Comment #19
Graham Knight commentedRe #12. I had a similar problem with unknown columns being flagged. If you print $query you will see arrays specifying the tables and fields that the Views module will use. I guess if would be possible to add the additional ones needed via the hook implementation code and so eliminate the error. However, I found the simplest way to achieve this was to include all the fields I intended to use in my hook implementation in the "Sort Criteria" on the Views edit form. The corresponding tables and fields will then appear in the $query data structure.
Comment #20
Siriki commentedMy problem solved by following below code. Below code is used for two content type date fields for sorting using views.
function modulename_views_query_alter(&$view, &$query) {
if ($view->name == 'views_name' && $view->current_display == 'display_name') {
// Completely replace current orderby
$query->orderby = array(
array(
// you need to actually do WHEN ... THEN once for each field, then a fallback
// Here added 2 content type date fileds
//two fields are for two content types i.e field_data_field_smk_date and field_data_field_pub_date
'field' => 'CASE WHEN
field_data_field_smk_date.field_smk_date_value THEN field_data_field_smk_date.field_smk_date_value
WHEN
field_data_field_pub_date.field_pub_date_value THEN field_data_field_pub_date.field_pub_date_value
ELSE node.created END',
'direction' => 'DESC',
)
);
}
}
Comment #21
gaspounet commentedFor Drupal 9.0.6 I had to do this way (in my case I have to sort two types of MEDIA entity on the same view, one that use a "field_date" and another one a "field_start_date", you can replace MEDIA by NODE or whatever entity type you use)
Comment #22
pgshehata commentedA solution that works for me
Comment #23
lehlohonolo commentedThank you @pgshehata.
Your solution works for on Drupal 9.1.X, I added a custom field(called User Name) on my View because I don't have a user fullname. It combines {{ first_name }} &
{{ last_name }}. Now I need to add direction to make it sortable either by ASC or DESC.
Thank you guys for this Question and solutions, I've been searching and searching.
Comment #24
ArchangelGuidz commented@Sensedrive - #16 worked great for me. Thanks!