-1
  $all_users =db_select('users', 'u')
  ->fields('u', array('uid'))
  ->execute()
  ->fetchAll();

  $quiz_nid = db_select('quiz_node_properties ', 'qnp')->distinct()
    ->fields('qnp',array('nid'))
    ->execute()
    ->fetchAll();

    foreach ($quiz_nid as $key => $value) {
      $quiz_id = $quiz_nid[$key]->nid;
      $quiz_takers = db_select('quiz_node_results', 'qnr')->distinct()
        ->fields('qnr',array('uid'))
        ->condition('nid',$quiz_id,'=')
        ->execute()
        ->fetchAll();
    }

$all_users is the list of all users. $quiz_takers is the list of users who have taken the quiz. Both $all_users and $quiz_takers are array of objects. I want list of users who have not taken the quiz. ($all_users - $quiz_takers). How to achieve this using not in(database query) or anything. Help needed.

2 Answers 2

2

This is quite straightforward by using a custom function. I think udiff might work too, but I'm going without that.

But before that make one modification

$quiz_takers_uid = db_select('quiz_node_results', 'qnr')->distinct()
        ->fields('qnr',array('uid'))id
        ->condition('nid',$quiz_id,'=')
        ->execute()
        ->fetchCol();

This gives you an array of uids in quiz_takers_uid.

function getdiff($all_users,$quiz_takers_uid) {
  $remaining_users = array();
  foreach ($allusers as $user) {
    if (array_search($user->uid,$quiz_takers_uid) !== FALSE)
      continue;
    else 
      $remaining_users[] = $user->uid;
  }
  return $remaining_users;
}

I just thought of something else, which would make it even shorter In fact, an alternative solution would be to also make

$all_users_uid =db_select('users', 'u')
  ->fields('u', array('uid'))
  ->execute()
  ->fetchCol();

then you could just do $remaining_users = array_diff($all_users_uid, $quiz_takers_uid);

as both are now arrays of uid.

0

If you have two array (one containing all the student, and another containing nids of students who took the quiz) than you try array_diff(): Computes the difference of arrays

$result = array_diff($array1, $array2);

Example:

<?php
  $array1 = array("a" => "green", "red", "blue", "red");
  $array2 = array("b" => "green", "yellow", "red");
  $result = array_diff($array1, $array2);

  print_r($result);
?>

The result will be Array ([1] => blue), you can see here the difference will of array1 from array2 so the result contains the elements of array1 not present in array2.

And this would be helpful as it won't require the additional database call.


However if you want to do it with the db_select query than check How do I use “NOT IN” in a query:

$query = db_select('node', 'n')->fields('n');
$query->condition('n.nid', array(1, 2, 3), 'NOT IN');
$nodes = $query->execute();

$query->condition('n.nid', $array2, 'NOT IN');

2
  • I have array of objects in both the cases. how to find out the difference between array of objects.? Oct 26, 2013 at 9:44
  • @neetumorwani Instead of fetchAll in your query USE ->fetchAllAssoc('uid'); $user_ids = array_keys($all_users);, this will provide you the uids or nid in an array Oct 26, 2013 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.