将行和/或列合并到GROUP BY中的一个字段中

时间:2014-05-01 23:21:01

标签: php mysql

我的SQL表看起来像

+-----+------------+--------------+--------------+-----------+------------+-----------+
| rid | ship_to_id | product_code | product_name | first_row | second_row | third_row |
+-----+------------+--------------+--------------+-----------+------------+-----------+
|   1 |        555 | A            | Crystal      | 1         | 2          | 3         |
|   1 |        555 | A            | Crystal      | 4         | 5          | 6         |
|   2 |        333 | B            | Diamond      | first     | second     | third     |
|   2 |        333 | A            | Crystal      | ROW 1     | ROW 2      | ROW 3     |
|   2 |        333 | A            | Crystal      | ROW 4     | ROW 5      | ROW 6     |
+-----+------------+--------------+--------------+-----------+------------+-----------+

我正在努力获得以下结果

+-----+------------+--------------+-------------------------------------+
| rid | ship_to_id | product_name |                data                 |
+-----+------------+--------------+-------------------------------------+
|   1 |        555 | Crystal      | 1 2 3 4 5 6                         |
|   2 |        333 | Diamond      | first second third                  |
|   2 |        333 | Crystal      | ROW 1 ROW 2 ROW 3 ROW 4 ROW 5 ROW 6 |
+-----+------------+--------------+-------------------------------------+

有人可以告诉我我的代码有什么问题。感谢

$query = mysql_query("SELECT * FROM mytable group by rid, ship_to_id, product_code, product_name");
while($row = mysql_fetch_array($query)) {
  echo "$row[rid] $row[ship_to_id] $row[product_code] $row[product_name] $row[first_row] $row[second_row] $row[third_row] <br>";
}

3 个答案:

答案 0 :(得分:0)

当您按前4列分组并且对其余列不使用聚合函数时,如果多个记录在分组的列中具有相同的值,则数据将丢失。 所以基本上结果如下:

+-----+------------+--------------+------------------------------------+
| rid | ship_to_id | product_name | first_row | second_row | thrid_row |
+-----+------------+--------------+------------------------------------+
|   1 |        555 | Crystal      | 1         | 2          | 3         |
|   2 |        333 | Diamond      | first     | second     | third     |
|   2 |        333 | Crystal      | ROW 1     | ROW 2      | ROW 3     |
+-----+------------+--------------+------------------------------------+

那是什么组合。要保留包含不同数据的字段的数据,必须对它们使用聚合函数,如GROUP_CONCAT。例如:

SELECT rid, ship_to_id, product_code, product_name, GROUP_CONCAT(first_row), GROUP_CONCAT(second_row), GROUP_CONCAT(third_row)
FROM mytable
GROUP BY rid, ship_to_id, product_code, product_name

这将连接相应记录的值,如下所示:

+-----+------------+--------------+------------------------------------------+
| rid | ship_to_id | product_name |  first_row  |  second_row  |  thrid_row  |
+-----+------------+--------------+------------------------------------------+
|   1 |        555 | Crystal      | 1 4         | 2 5          | 3 6         |
|   2 |        333 | Diamond      | first       | second       | third       |
|   2 |        333 | Crystal      | ROW 1 ROW 4 | ROW 2 ROW 5  | ROW 3 ROW 6 |
+-----+------------+--------------+------------------------------------------+

但是,对于这种情况,您使用GROUP BY的方法可能不是最好的方法。值得考虑按rid, ship_to_id, product_code, product_name列排序,然后在给定顺序的PHP中迭代它们并合并相应的行。

您可能还需要重新考虑数据库设计,因为像这样的查询闻起来有一个坏概念:)

答案 1 :(得分:0)

你可以试试像

这样的东西
select rid,ship_to_id,product_name,
GROUP_CONCAT(CONCAT(first_row,' ',second_row,' ',third_row) as new_val
from mytable
group by rid,ship_to_id,product_name;

答案 2 :(得分:0)

  1. 我猜你有时会忘记product_code。
  2. 这可能是糟糕的数据库设计。您应该了解Database normalization及相关技术。
  3. 第三,SQL通常为每个结果记录生成相同数量的列,因此您可能拥有的最佳结果包含1, 555, "A", "Crystal", "1 4 2 5 3 6"行(请注意这些是5个值)。但是我想不出一种能够产生1 2 3 4 5 6顺序的数字的连接方法。根据数据库架构的更好形式,这可能比PHP更容易在PHP中完成。
  4. 如果您仍然要将所有值连接到单个单元格中(如新格式化的示例输出中那样),那么您应该尝试以下几行:

    SELECT
        rid, ship_to_id, product_code, product_name,
        GROUP_CONCAT(CONCAT(first_row,'#',second_row,'#',third_row) SEPARATOR '~') AS data
    FROM tablename
    GROUP BY rid, ship_to_id, product_code, product_name;
    

    请注意,first_row等的值用'#'分隔,而不同记录的值用'〜'符号分隔。您可以在documentation of MySQL's GROUP_CONCAT()中找到更多选项。