0
SELECT
    `s1`.`question`,
    GROUP_CONCAT(QUOTE(`so1`.`name`)) `answers`
FROM
    `survey` `s1`
INNER JOIN
    `survey_option` `so1`
ON
    `so1`.`survey_id` = `s1`.`id`
GROUP BY
    `s1`.`id`;

此查询将产品question列表answer作为带引号的逗号分隔字符串。

如何将答案字符串扩展为数组?

我首先想到的是explode("','", mb_substr($answers_str, 1, -1))

有什么我应该注意的问题吗?

4

2 回答 2

0

我让这个问题听起来比实际上更难。我的解决方案没有直接回答我的问题,尽管它解决了根本问题。

我需要为报告门户生成数据导出,其中有一组定义的变量(例如,名字、姓氏等)+ 随时间变化的数据变量(即,必须根据是否存在包含或排除在定义的时间间隔内)。此外,它必须以 Excel 友好格式(例如 csv)生成(因此第一次尝试使用 GROUP CONCATination 使用逗号)。

我采用的解决方案是动态查询生成

public function getCombined/*[..]*/ (array $filter = []) {
    // Find the columns
    $freeform_data = $this->db
        ->prepare("
        SELECT
            DISTINCT `dpd1`.`name`
        FROM
            `device_product` `dp1`
        INNER JOIN
            `device_product_data` `dpd1`
        ON
            `dpd1`.`device_product_id` = `dp1`.`id`;
        ")
        ->execute([$filter)
        ->fetchAll(\PDO::FETCH_COLUMN);

    $freeform_data_selectors = '';
    $freeform_data_join = '';

    foreach ($freeform_data as $i => $name) {
        if ($name != preg_replace('/[^a-z_-]/i', '', $name)) {
            throw new \ErrorException('Invalid freeform data input name ("' . $name . '").');
        }

        $alias = '`dpd' . ($i + 1) . '`';

        $freeform_data_selectors .= ', ' . $alias . '.`value` `freeform_' . $name . '`';

        $freeform_data_join .= '
        LEFT JOIN
            `device_product_data` ' . $alias . '
        ON
            ' . $alias . '.`device_product_id` = `dp1`.`id` AND
            ' . $alias . '.`name` = \'' . $name . '\'
            ';
    }

    $stmt = $this->db
        ->prepare("
        SELECT
            `d1`.`mac_address` `device_mac_address`,            
            {$freeform_data_selectors}
        FROM
            `device_product` `dp1`          
        {$freeform_data_join}
        GROUP BY
            `dp1`.`id`;", [\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false])
        ->execute($filter);

    return stmt;
}

这是一个精简的例子,它可能看起来类似于 Robin Castlin 的建议。但是,实际查询还有另外 10 个连接和一个大型数据集 (2M+)。Castlin 的建议需要更多的资源来检索和组织数据。

于 2013-07-19T08:43:24.400 回答
0
# Run query
SELECT
#   `s1`.`id`,
    `s1`.`question`,
    `so1`.`name`
FROM
    `survey` `s1`
INNER JOIN
    `survey_option` `so1`
ON
    `so1`.`survey_id` = `s1`.`id`

# Fetch query
$arr = array();
while($row = mysql_fetch_object($query))
    $arr[$row->question][] = $row->name;

# If question's aren't unique, you can also fetch 'id' in query and:
$arr = array();
while($row = mysql_fetch_object($query))
    $arr[$row->id][] = $row;

这假设您将查询值保存为$query. GROUP_CONCAT如果您打算事后将它们分开,那么这样做是没有意义的。只需使用一个数组和它的键值就足够了。

于 2013-07-15T09:33:37.437 回答