Zend Framework高级WHERE IN查询

时间:2012-05-14 01:32:21

标签: zend-framework zend-db-table

所以,我已经提出了这个查询,它在执行时完美无缺。但是,由于我想使用Zend的分页,查询必须通过适配器。

这是必须转换的查询:(我已经删除了查询,因此只有重要的部分在这里。我知道您无法运行此查询LOL)

//snip
WHERE
    city IN (
        SELECT 
            Plaatsnaam
        FROM
            plaatsnamen
        WHERE
            Latitude 
                BETWEEN 
                    ?
                AND 
                    ?
        AND
            Longitude
                BETWEEN
                    ?
                AND
                    ?       
    )
//snip

完美无缺!但是..正如你所看到的,我正在使用“高级”WHERE IN案例。不知怎的,我不能让这个转换,我被卡住了。

这是必须转换为:

$db = Zend_Db_Table::getDefaultAdapter();                
$select = $db->select('gethousecity.id, city')
                                ->from('gethousecity')
                                    ->join('houses_props', 'houses_props.id = gethousecity.id')
                                ->where('city IN ()') // HOW TO CONVERT THE UPPER QUERY TO FIT IT HERE?
                                ->where('is_online = 1')
                                ->where('houses_props.prop_name = ?', 'something')
                                ->where('houses_props.prop_value BETWEEN ? AND ?', array(1,2));

我还没有找到任何关于如何将查询转换为适合此处的格式的文档。有谁有想法吗?主要是因为我需要插入一些值,而ZF正在重写一些奇怪的狗屎。

我现在有点困惑,任何帮助都会很棒!

4 个答案:

答案 0 :(得分:3)

子查询工作正常。

$select1->cols('id')->where('date > NOW()');
$select2->where('id IN (?)', $select1);

如果问题是复杂的地方,那么你可以使用命名参数。

$select1 = $db->select();
$select2 = $db->select();
$select1->from('plaatsnamen', array('Plaatsnaam'))
        ->where('Latitude BETWEEN :latmin AND :latmax')
        ->where('Longitude BETWEEN :longmin AND :longmax');
$select2->from('gethousecity')
        ->join('houses_props', 'houses_props.id = gethousecity.id')
        ->where('city IN ?', $select1) // HOW TO CONVERT THE UPPER QUERY TO FIT IT HERE?
        ->where('is_online = 1')
        ->where('houses_props.prop_name = ?', 'something')
        ->where('houses_props.prop_value BETWEEN :propsmin AND :propsmax');
die($select2);

返回:

SELECT `gethousecity`.*, `houses_props`.*
FROM `gethousecity`
INNER JOIN `houses_props` ON houses_props.id = gethousecity.id
WHERE 
    (city IN (
        SELECT `plaatsnamen`.`Plaatsnaam`
        FROM `plaatsnamen`
        WHERE 
        (Latitude BETWEEN :latmin AND :latmax) AND
        (Longitude BETWEEN :longmin AND :longmax)
    )) AND
    (is_online = 1) AND
    (houses_props.prop_name = 'something') AND
    (houses_props.prop_value BETWEEN :propsmin AND :propsmax)

哪个应该适用于命名参数,如manual

中所示
$bind = array(
    ':latmin' => 10,
    ':latmax' => 3,
    '...' => '...',
);
$db->fetchAll($select2, $bind);

答案 1 :(得分:0)

据我所知,ZF DB没有对子查询的原生支持。

您可以尝试这样做:

// snip
->where("city IN (
    SELECT Plaatsnaam
    FROM plaatsnamen
    WHERE Latitude BETWEEN $lowLat AND $highLat
      AND Longitude BETWEEN $lowLon AND $highLon
)")
// snip

编辑:将值直接插入到条件字符串中,只有当变量是可信的时才这是安全的(或者如果你从用户那里得到它们,请确保在执行此操作之前将它们转换为浮点数)。

或者,您可以尝试避免使用子查询,而是进行连接,但这可能会对性能产生影响(可能更好或更差)。

答案 2 :(得分:0)

最后,作为一个快速的解决方法,我想出了以下内容; $ DB->报价

$select = $db->select('gethousecity.id, city')
                                    ->from('gethousecity')
                                        ->join('houses_props', 'houses_props.id = gethousecity.id')
                                    ->where('city IN (  
                                                    SELECT Plaatsnaam
                                                    FROM plaatsnamen
                                                    WHERE Latitude BETWEEN '.$latlon_search[0].' AND '.$latlon_search[1].'
                                                        AND Longitude BETWEEN '.$latlon_search[2].' AND '.$latlon_search[3].'
                                    )') 
                                    ->where('is_online = 1')
                                    ->where('houses_props.prop_name = ?', 'vraagprijs[vraagprijs]')
                                    ->where('houses_props.prop_value BETWEEN '.$db->quote($price_start).' AND '.$db->quote($price_end));

对我而言,这是实现这项工作的唯一途径。我每次都这样做:

->where('statement ? AND ?', array($val1, $val2)

结果如下:

statement val1,val2 AND val1,val2

答案 3 :(得分:0)

试试这个

 $db = Zend_Db_Table::getDefaultAdapter();  
    $selectInner = $db->select()->from('plaatsnamen','Plaatsnaam')
                   ->where("Lattitude BETWEEN $lowLat AND $highLat")
                   ->where("Longitude BETWEEN $lowLon AND $highLon")
                   ->__toString();



    $select = $db->select('gethousecity.id, city')
                                    ->from('gethousecity')
                                        ->join('houses_props', 'houses_props.id = gethousecity.id')
                                    ->where("city IN ($selectInner)");