所以,我已经提出了这个查询,它在执行时完美无缺。但是,由于我想使用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正在重写一些奇怪的狗屎。
我现在有点困惑,任何帮助都会很棒!
答案 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)");