31

I am having some problems turning the SQL below into a Zend Db query.

$select = ' SELECT s.id, i.id as instance_id, i.reference, i.name, i.sic_code, i.start_date
                FROM sles s
                JOIN sle_instances i
                ON s.id = i.sle_id
                WHERE i.id = (  SELECT MAX(id) 
                                FROM sle_instances 
                                WHERE sle_id = s.id
                                )
                ORDER BY i.name ASC';

I have got as far as the code before - but Zend Db isn't producing the query correctly. Can any one show me what I missing??

$select = $db->select() ->from('sles', array(   'id',
                                                'instance_id'   => 'sle_instances.id',                                                                                          
                                                'reference'     => 'sle_instances.reference',           
                                                'name'          => 'sle_instances.name',
                                                'sic_code'      => 'sle_instances.sic_code',
                                                'start_date'    => 'sle_instances.start_date'
                                             )
                              )
                        ->join('sle_instances', 'sles.id = sle_instances.sle_id')
                        ->where('sles.id = (SELECT MAX(id) FROM sle_instances WHERE sle_id = sles.id)')
                        ->order('sle_instances.name ASC');

The SQL does work by the way. I am rewriting it using Zend Db as I wish to use the Zend Paginator functionality.

Any help is greatly appreciated.

PJ

0

4 Answers 4

35

if you want, you can take what @karim79 did and turn your subselect into a $this->select() as well...

$subselect = $db->select()
->from('sle_instances', array(new Zend_Db_Expr('max(id)')))
->where('sle_id = s.id');

$select = $db->select()->from(array("s" => "sles"), 
array("s.id","i.id as instanceid","i.reference","i.name","i.sic_code","i.start_date"))
->join(array('i' => "sle_instances"),"s.id = i.sle_id",array())
->where("i.id = ($subselect)")
->order('i.name asc');

print($select);

//SELECT `s`.`id`, `i`.`id` AS `instanceid`, `i`.`reference`, `i`.`name`, `i`.`sic_code`, `i`.`start_date` FROM `sles` AS `s` INNER JOIN `sle_instances` AS `i` ON s.id = i.sle_id WHERE (i.id = (SELECT max(id) FROM `sle_instances` WHERE (sle_id = s.id))) ORDER BY `i`.`name` asc
Sign up to request clarification or add additional context in comments.

1 Comment

@PratikCJoshi, $db is a Zend_Db_Table instance in most cases.
22

This:

    $select = $db->select()->from(array("s" => "sles"), array("s.id","i.id as instanceid","i.reference","i.name","i.sic_code","i.start_date"))
                                 ->join(array('i' => "sle_instances"),"s.id = i.sle_id",array())
                                 ->where("i.id = (select max(id) from sle_instances where sle_id = s.id)")
                                 ->order('i.name asc');

Gives this:

"SELECT `s`.`id`, `i`.`id` AS `instanceid`, `i`.`reference`, `i`.`name`, `i`.`sic_code`, `i`.`start_date` FROM `sles` AS `s`
 INNER JOIN `sle_instances` AS `i` ON s.id = i.sle_id WHERE (i.id = (select max(id) from sle_instances where sle_id = s.id)) ORDER BY `i`.`name` asc"

2 Comments

Thanks Karim. It took me a while to work out what was different - it was the id match in the where statement - silly mistake!! But good to know I wasn't too far off!
@PJE - I couldn't see what the problem was by looking at your code, I built the select from scratch using your query, and now you've pointed that out I see it!
4

Great question! Thank you for this one. Also wanted to throw out that if you are trying to do a group after an order, you can also use this syntax by something very similar to the following

$subquery = $this->_datawarehouse->select()
            ->from('revenueLog')
            ->where('Date '.$ReturnDate)
            ->order('Date DESC');

        $this->view->end = microtime();
        $format = new Zend_Db_Expr('DATE_FORMAT(`Date`,"%d-%m-%y")');
        $select = $this->_datawarehouse->select()
                ->from(array('subquery'=>$subquery))
                ->group('Client')
                ->group($format)
                ->order('Vertical ASC')
                ->order('Revenue DESC');

        echo $select->__ToString();
        $stmt = $this->_datawarehouse->query($select);
        $data = $stmt->fetchAll();

for anyone wondering $ReturnDate is a string based on a user input, which usually ends up being a "BETWEEN 'date1' AND 'date2'"

Comments

3

I had a very similar problem and I found that this query can be easily written as follows:

$select = $db->select()
  ->from (
    array("s" => "sles"), 
    array(
      "s.id",
      "instanceid" => "i.id",
      "i.reference",
      "i.name",
      "i.sic_code",
      "i.start_date")
  )
  ->join(
    array('i' => "sle_instances"),
    "s.id = i.sle_id",
    array()
  )
  ->where ("i.id = (" . 
    $db->select()
    ->from('sle_instances', array(new Zend_Db_Expr('max(id)')))
    ->where('sle_id = s.id');
  .")")
  ->order('i.name asc');
print($select);

It is exactly the same as people has already stated here. But I felt it is a little easier to read since the sub-query dependencies are more evident.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.