Zend_Db_Select如何从子查询中选择(派生表)

时间:2011-10-12 01:06:21

标签: php mysql database zend-framework

如何使用Zend_Db_Select直接从子查询(派生表)中进行选择?

请参阅,我有5个具有相同结构的表,我想从中获取所有行,合并它们并删除重复项。我正在使用UNION自动删除重复项。问题是我之前为每个表添加了一个静态列,因此有一列不同=>重复发生。

到目前为止,这是我的查询:

SELECT `news_main`.*, 'main' as `category` 
FROM `news_main` 
UNION SELECT `news_politics`.*, 'politics' as `category` FROM `news_politics` 
UNION SELECT `news_society`.*, 'society' as `category` FROM `news_society` 
UNION SELECT `news_world`.*, 'world' as `category` FROM `news_world` 
UNION SELECT `news_business`.*, 'business' as `category` FROM `news_business` 
ORDER BY `date` DESC LIMIT 8

了解如何将静态值添加到新列category?现在其他一切都是相同的(有重复的行),但由于它们来自不同的类别,UNION无法删除它们。

所以我想我可以SELECT来自这个子查询的所有行,并将它们分组以删除重复项,如下所示:

SELECT * 
FROM (
    SELECT `news_main`.*, 'main' as `category` 
    FROM `news_main` 
    UNION SELECT `news_politics`.*, 'politics' as `category` FROM `news_politics`
    UNION SELECT `news_society`.*, 'society' as `category` FROM `news_society` 
    UNION SELECT `news_world`.*, 'world' as `category` FROM `news_world` 
    UNION SELECT `news_business`.*, 'business' as `category` FROM `news_business` 
    ORDER BY `date` DESC LIMIT 8
) as subtable 
GROUP BY `source` 
ORDER BY `date` DESC

我在MySQL中运行它并且它完美运行..唯一的问题是......

如何使用Zend_Db_Select的花哨功能执行此操作?

提前致谢!

3 个答案:

答案 0 :(得分:1)

我不确定你是否可以在Zend_Db_Select的from结构中使用嵌套选择,或者你是否应该这样做,但另一种解决方案是获取db适配器并手动构建sql查询。

$db = Zend_Db_Table::getDefaultAdapter();
$db->query("SELECT * 
    FROM (
        SELECT `news_main`.*, 'main' as `category` 
        FROM `news_main` 
        UNION SELECT `news_politics`.*, 'politics' as `category` FROM `news_politics`
        UNION SELECT `news_society`.*, 'society' as `category` FROM `news_society` 
        UNION SELECT `news_world`.*, 'world' as `category` FROM `news_world` 
        UNION SELECT `news_business`.*, 'business' as `category` FROM `news_business` 
        ORDER BY `date` DESC LIMIT 8
    ) as subtable 
    GROUP BY `source` 
    ORDER BY `date` DESC
");

相关: Zend_Db_Table subquery

答案 1 :(得分:0)

从Zend_Db_Select的源代码我可以看出,它的from()方法调用它的_join()方法,该方法有一个案例表明from()的第一个参数是Zend_Db_Select对象:http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Db/Select.php

} else if ($name instanceof Zend_Db_Expr|| $name instanceof Zend_Db_Select) {
        $tableName = $name;
        $correlationName = $this->_uniqueCorrelation('t');

如果没有,from()应该通过将子查询包装在子括号中来强制将它强制转换为Zend_Db_Expr实例,如本例中的joinRight()所示:Zend Framework: Zend_Db_Select - how to join custom subquery table?

答案 2 :(得分:0)

只需定义一个引用子查询的类,然后您就可以在一个地方添加更多处理:

class Acme_Db_Expr_Subquery extends Zend_Db_Expr {
    public function __toString()
    {
        return '( ' . $this->_expression . ' )';
    }
}

然后在FROM子句中使用它(我的情况,来自实际应用的copypaste,工作)或JOIN(推测,没试过)。

$innerSelect = $dbTableSomeModel->select(true);
// Configure it, maybe kick around many layers of abstarction

$nestedSelect->from(
    array(
        'derived_alias' => new Acme_Db_Expr_Subquery( $innerSelect ),
    )
    ,array(
        'column_alias' => 'column_expression',
    )
);