2

i have the folowing query in SQL

... where group_id IN (select group_id from alert where monitor_id = 4);

I want to write it in Doctrine but i don't know how to add the IN select into WHEREIN() clause ! any idea ?

this is what i did

$q = $this->createQuery('u') 
    ->select('u.email_address') 
    ->distinct(true)
    // ->from('sf_guard_user u') 
    ->innerJoin('u.sfGuardUserGroup ug') 
    ->where('ug.group_id IN(select group_id from alert where monitor_id=?',$monitor);     

$q->execute(); 

In the sfGuardUserTable.class:

public function getMailsByMonitor($monitor) {


        $q = Doctrine_Query::create()->from("alert a")->where("a.monitor_id", $monitor);
        $groups_raw = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
        $groups = array();
        print_r($groups_raw);
        foreach ($groups_raw as $gr) {
            $groups[] = $gr->id; //line 33
        }


        $q2 = $this->createQuery('u')
                ->select('u.email_address')
                ->distinct(true)
                ->innerJoin('u.sfGuardUserGroup ug')
                ->whereIn("ug.group_id", $groups);
        return $q2->execute();
    }
ProXamer
  • 377
  • 1
  • 9
  • 25
  • not related to the actual question but to the use of this query: Which RDBMS are you using? – ypercubeᵀᴹ Aug 26 '11 at 10:04
  • Do you use Symfony-1.4 with Doctrine 1.2 or are you using Symfony2 with doctrine2? (confusing tags) – Flask Aug 26 '11 at 10:15
  • Symfony-1.4 with Doctrine 1.2 – ProXamer Aug 26 '11 at 10:43
  • Are that `// before `->from('sf_guard_user u')` relevant? – J0HN Aug 26 '11 at 11:40
  • @SymFoNyBegginer: Consider rewritting the query using `JOIN` or even better with `WHERE EXISTS` than with `IN`. MySQL's execution plan for `x IN (SELECT y FROM z)` is known to be not optimal. It's not very bad if your tables are small (in number of records) but if they are big you'll notice difference in speed. – ypercubeᵀᴹ Aug 26 '11 at 11:43

2 Answers2

6

Usually you would do something like:

$q = Doctrine_Query::create()
  ->from('User u')
  ->whereIn('u.id', array(1, 2, 3));

But I think this one better fits your needs:

$q = Doctrine_Query::create()
  ->from('Foo f')
  ->where('f.group_id IN (SELECT f.group_id FROM Alert a WHERE a.monitor_id = ?)', 4);
Flask
  • 4,966
  • 1
  • 20
  • 39
  • why do you select a.grou p_id from alert (make sure there is no space inbetween). – Flask Aug 26 '11 at 10:15
  • SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in y our SQL syntax; check the manual that corresponds to your MySQL server version f or the right syntax to use near '' at line 1 – ProXamer Aug 26 '11 at 10:18
  • would it be possible to add the relating schema.yml part to your question and your current dql query? – Flask Aug 26 '11 at 10:20
  • that's the peace of query: ->where('ug.group_id IN(select group_id from alert where monitor_id=?',$monitor); – ProXamer Aug 26 '11 at 10:20
  • $q = $this->createQuery('u') ->select('u.email_address') ->distinct(true) // ->from('sf_guard_user u') ->innerJoin('u.sfGuardUserGroup ug') ->where('ug.group_id IN(select group_id from alert where monitor_id=?',$monitor); $q->execute(); – ProXamer Aug 26 '11 at 10:21
0

One possible solution - fetch select group_id from alert where monitor_id = 4 into an array and use it in whereIn

$q = Doctrine_Query::create()->from("alert a")->where("a.monitor_id", 4);
$groups_raw = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
$groups = array();
foreach ($groups_raw as $gr){
    $groups[] = $gr->id;
}

$q2 = Doctrine_Query::create()->from("table t")->whereIn("t.group_id", $groups);

Two queries instead of one, but definitely do the trick.

J0HN
  • 26,063
  • 5
  • 54
  • 85
  • i don't realy understand your query ! – ProXamer Aug 26 '11 at 10:56
  • The idea: fetch all group ids into an array with first query, than use this array in `whereIn` in second query to retrieve the final result. – J0HN Aug 26 '11 at 11:07
  • i get this error : c:\Dev\sfMonitoring>symfony monitorsRetreive PHP Notice: Trying to get property of non-object in C:\Dev\sfMonitoring\lib\mod el\doctrine\sfDoctrineGuardPlugin\sfGuardUserTable.class.php on line 33 – ProXamer Aug 26 '11 at 11:54
  • this is line 33: $groups[] = $gr->id; – ProXamer Aug 26 '11 at 11:54
  • That means nothing to me. I don't have your code here, could you update the question with the code that produces this error (and please, don't forget to mark line 33 :) – J0HN Aug 26 '11 at 11:55
  • Ah, my fault :) Change `HYDRATE_ARRAY` to `HYDRATE_OBJECT` **or** `$gr->id` to `$gr['id']`. – J0HN Aug 26 '11 at 11:56
  • Unknown record property / related component "id" on "Alert" any ideaaaas ?? – ProXamer Aug 26 '11 at 13:17
  • Well, that was your homework, I think your `Group` table have index column named `group_id` :) – J0HN Aug 26 '11 at 13:35
  • Replace `$gr->id` with `$gr->group_id` – J0HN Aug 26 '11 at 13:59
  • it seems that this code bloks the computer! the process is taking more than 5minutes and still not finished yet ! – ProXamer Aug 26 '11 at 14:25