Hello! First of all: Thanks for the great module! It's a great help and saves a lot of SQL hacking, great!

Today I experimented with this module and had a look at the generated SQL statements. As it seems, arguments I add to a view are interpreted in an additive way resulting the SQL having the according filtering statements connected with 'AND' in its WHERE-part. It is not possible to conjunct arguments in an disjunctive way, which would be reflected with 'OR' conjunctions in the resulting SQL query.

Example: Let's say i want to filter after two arguments, the first giving the user name and the second some taxonomy term name: A request like somehost/Clint/Drupal will be reflected in the SQL statement like:

...
WHERE 
  (users.name = 'Clint') AND 
  (term_data.name = 'Drupal')

If I now want to filter with another third taxonomy term argument, an appropriate query like somehost/Clint/Drupal/Cms should be interpreted as:

...
WHERE 
  (users.name = 'Clint') AND 
  (term_data.name = 'Drupal' OR
  term_data.name = 'Cms')

But as all arguments are connected with 'ADD', in the moment it will result in a useless SQL query:

...
WHERE 
  (users.name = 'Clint') AND 
  (term_data.name = 'Drupal') AND
  (term_data.name = 'Cms')

Thus, I propose the introduction of a way to apply arguments in a disjunctive way (OR). Maybe it is possible to bundle arguments of the same type into an OR-group. Seems like a natural fit for me, because (at least in my example) it makes no sense to filter the same argument type twice in an additive way: (term_data.name = 'Drupal') AND (term_data.name = 'Cms') is a pointless request.

Comments

mfredrickson’s picture

See also http://en.wikipedia.org/wiki/Conjunctive_normal_form for a formal write up on what you're proposing. I'd like to see this.

To do so, we'd probably have to change the view's object, such that filters are grouped, instead of being a flat list. Also, we'd need UI changes to add the filter groups. Finally, there would be the problem of exposed filters. From a data perspective, exposed filters would be fairly simple, but from a UI perspective, it could be very confusing. For example, if I had a view with the filter groups

Taxonony Terms (exposed)
Author  = Fred

OR 

Taxonomy Terms (exposed)
Author = Joe

It could be very confusing to have two sets of terms. Moreover - what I always wanted those taxonomy terms linked (i.e. the say terms selected in each OR group).

This is a good idea, but I think we should spend a little time specing out exactly how the system behaves before charging ahead. :-)

henmue’s picture

Yeah, the form should correspond to CNF. I did not want to mention the conjunctive normal form, because boolean logic is a bit far-fetched, but what the heck! No worries. :-)

From the perspective of flexibility, a full reproduction of SQLs abilities would be best. That is, as you pointed out, a little more complicated as the current AND-conjunction of arguments. That's why I thought of the automism of bundling arguments of the same type, I think an AND-conjunction is of no use in this case.

If you want to go all out and implement arbitrary "conjunctive normal forms", I see two possibilities. The first is to change the whole GUI accordingly, which is a bit much for my taste. The second option which comes to my mind is some kind of composition instruction. If your had four arbitrary arguments you could state in a single line something like

( 1 | 2 ) + ( 3 | 4 )

that your arguments shall be interpreted like

SELECT
  ...
WHERE
  (statement_1 = value_1 OR
  statement_2 = value_2) AND
  (statement_3 = value_3 OR
  statement_4 = value_4)

That could keep the GUI as is but provide the whole flexibility.

catch’s picture

Version: 5.x-1.6-beta4 » 6.x-2.x-dev

Did this make it into Views 2?

lokisapocalypse’s picture

Version: 6.x-2.x-dev » 5.x-1.6

I agree that this would be a very useful feature and would like to see it be a part of views. I don't believe it should replace AND but allow users to choose.

scottrigby’s picture

Title: Allo disjunctive conjunction (OR) of arguments » Allow disjunctive conjunction (OR) of arguments
Version: 5.x-1.6 » 6.x-2.x-dev
Status: Active » Postponed

@lokisapocalypse: new features will go into 6.x first.

@catch not yet :p -- but from a conversation with merlinofchaos on IRC it looks like this feature will only happen after we can do the same thing with filters.
Here's a link to the filters issue help keep track of the status #118672: Adding sql ORing capability with filters

Also marking #334883: Extending the WHERE clause in argument handling code as duplicate of this issue.

catch’s picture

scottrigby’s picture

@catch: right - Though sadly, from what merlinofchaos said at #3 in that issue and clarified today - Arguments didn't get the underlying structure filters did to support grouping :( so it looks like views_or module will only work for filters in the meantime but not yet for arguments.

Unless there's some other way to do this using arguments currently -- I mean, if you know about any provisional method for doing this? i'd love to try it out -- I don't have any other leads on ORing arguments :p

emi_bcn’s picture

+1

henmue’s picture

@all

Hi! Never thought that this issue would live for so long... :o)

I had no time to try it out, but the views_or module descrition states that it can handle arguments as well.

Regards Henry

murz’s picture

Subscribe

entrigan’s picture

Version: 6.x-2.x-dev » 6.x-3.x-dev
zeppie’s picture

subscribe,

Rearranging filters works perfectly!! a simular UI for arguments would be be great!! (or am I missing something and is this already possible? )

not_Dries_Buytaert’s picture

BTW: The module suggested in post #6 (6.x-1.x-dev d.d. 2010-Jul-11: http://drupal.org/node/289567) seems to work also for arguments (not only filters).
An example SQL-statement WITHOUT the module installed, enabled and configured (i.e. AND-ing):

SELECT node.nid AS nid,
   node.title AS node_title
 FROM node node 
 LEFT JOIN content_field_managers node_data_field_managers ON node.vid = node_data_field_managers.vid
 INNER JOIN users users ON node.uid = users.uid
 WHERE (node_data_field_managers.field_managers_uid = 1) AND (users.uid = 1)
   ORDER BY node_title ASC

The same SQL-statement WITH the module installed, enabled and configured (i.e. OR-ing):

SELECT node.nid AS nid,
   node.title AS node_title
 FROM node node 
 LEFT JOIN content_field_managers node_data_field_managers ON node.vid = node_data_field_managers.vid
 LEFT JOIN users users ON node.uid = users.uid
 WHERE (node_data_field_managers.field_managers_uid = 1) OR ((users.uid = 1) AND (users.uid IS NOT NULL))
   ORDER BY node_title ASC

So, only the JOIN and WHERE parts differ. I doubt whether the JOIN part should have changed from an inner to a left outer. So, I don't know whether the suggested module would be a safe workaround for this issue.

esmerel’s picture

Status: Postponed » Closed (duplicate)

Views or is already part of views 3. #118672: Adding sql ORing capability with filters

entrigan’s picture

Status: Closed (duplicate) » Active

That is for ORing filters. This issue is about arguments.

merlinofchaos’s picture

Status: Active » Closed (won't fix)

That is correct. However, I'm sorry to say that I am not going to consider applying OR to arguments at this time. The complexity of doing so is vast and I am not sure we can ever do it properly without a serious redesign of how arguments and filters interact.

danmuzyka’s picture

In case anyone else out there is using Views 6.x-3.x and trying to OR together arguments, here is the workaround that our team implemented.

Our use case was to create a view listing books that were either written, illustrated, edited, etc. by a given person. We had a content type 'book' and a content type 'contributor.' 'Book' type nodes had several nodereference fields that could point to nodes of type 'contributor.' These nodereference fields included: author, editor, illustrator, photographer, translator, etc. Our goal was to pass in one nid to the view, and to show all book nodes where that nid appeared in at least one of those nodereference fields.

Here is how we did it using Views 6.x-3.x and a simple views hook function. First, we created a view with a Global: Null argument. Then we set up filters corresponding to what we wanted to use as arguments. In our case, these were Content: Author, Content: Editor, Content: Illustrator, Content: Photographer, and Content: Translator. We didn't select any nodes from the is one of list, so in the Filters list for the view they all ended in the 'Unknown.'

Next, we changed the Use grouping setting under Advanced settings to Yes, grouped together the nodereference field filters, and set the Group Operator to OR. Finally, we used hook_views_pre_build() in a custom module to assign the value of the Global: Null argument to the filter fields:

/**
 * Implementation of hook_views_pre_build().
 */
function MYMODULE_views_pre_build(&$view) {
  switch ($view->name) {
    case 'contributor_works_listing':
      $contributor_nid = $view->args[0];
      $view->filter['field_contributor_author_nid']->value[$contributor_nid] = $contributor_nid;
      $view->filter['field_contributor_editor_nid']->value[$contributor_nid] = $contributor_nid;
      $view->filter['field_contributor_illustrator_nid']->value[$contributor_nid] = $contributor_nid;
      $view->filter['field_contributor_photographer_nid']->value[$contributor_nid] = $contributor_nid;
      $view->filter['field_contributor_translator_nid']->value[$contributor_nid] = $contributor_nid;
      break;
    default:
      break;
  }
}

This relatively simple approach worked!

seandunaway’s picture

Great thinking and thanks for sharing danmuzyka! This works great with content fields but for some reason taxonomy are 'ungroupable'.

leelooch’s picture

Thanks danmuzyka for this workaround.
How do you solve the "No valid values found on filter" error that prevents from saving the view because of the filter values set to "unknown" ?

Update : It's OK, I found my own workaround by putting Node: Nid filters on relationships and assigning the value of arg[0] to fields that look like : $view->filter['nid']->value['value'] ($dpm($view); to see what it looks like)
thanks again !