How does one convert complex SQL queries into Zend_Db_Select statements?

半世苍凉 提交于 2019-12-12 20:05:35

问题


The MySQL website has an excellent tutorial on storing hierarchal data in a database. I'm trying to write the query that returns a node's immediate children. I don't want to just copy/paste the query from the MySQL website, because I'm trying to work on this in a database agnostic manner.

This is the query I'm trying to Zend_Db_Select-ify

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
    nested_category AS parent,
    nested_category AS sub_parent,
    (
        SELECT node.name, (COUNT(parent.name) - 1) AS depth
        FROM nested_category AS node,
        nested_category AS parent
        WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.name = 'PORTABLE ELECTRONICS'
        GROUP BY node.name
        ORDER BY node.lft
    )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
    AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
    AND sub_parent.name = sub_tree.name
GROUP BY node.name
ORDER BY node.lft;

回答1:


You can try spliting your query into two Zend_Db_Select statements - parent query and subquery. You can use Zend_Db_Select object as param of from() method, like below:

$mainQuery = $db->select();
$mainQuery->from('user');

$sub = $db->select();
$sub->from('company');

$mainQuery->from(array('subquery' => $sub));

And you will get that kind of query:

SELECT `user`.*, `sub`.* FROM `user` 
    INNER JOIN (
        SELECT `company`.* FROM `company`
    ) AS `sub`

As you see, it automatically adds INNER JOIN when you add second from() - but I think, it's possible to rewrote your query to user joins instead of multi from syntax. So you should use joinInner() method, because then you can specify join condition as second param of it.

Notice, that subquery is similar to main query, so you could build main query, clone it as subquery, and thanks to Zend_Db_Select possibilities remove unnecessary parts (reset() method) and replace them:

$mainQuery = $db->select(); //and rest
$subQuery = clone $mainQuery;
$subQuery->reset(Zend_Db_Select::WHERE);
$subQuery->where(); // and add valid conditions for subquery



回答2:


You can just paste in the query directly like this

$result = $db->query("SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
        FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
            SELECT node.name, (COUNT(parent.name) - 1) AS depth
            FROM nested_category AS node,
            nested_category AS parent
            WHERE node.lft BETWEEN parent.lft AND parent.rgt
            AND node.name = 'PORTABLE ELECTRONICS'
            GROUP BY node.name
            ORDER BY node.lft
        )AS sub_tree
    WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
    GROUP BY node.name
    ORDER BY node.lf");

Be sure to use quote() to input any of your own parameters into this query.

This is a bit of a cheat and isn't something I have resorted to yet.



来源:https://stackoverflow.com/questions/4883583/how-does-one-convert-complex-sql-queries-into-zend-db-select-statements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!