经过多次使用CONCAT()之后,我从数据库中获得了这种字符串。
1, AA, 6, 10; 1, Z, 1, 5; 2, AE, 1, 5; 2, AF, 6, 10; 3, X, 1, 5; 3, Y, 5, 10
为了清楚一些,让我们这样说:
;
Group
Section
From
To
使用此代码
$data = "1, AA, 6, 10; 1, Z, 1, 5; 2, AE, 1, 5; 2, AF, 6, 10; 3, X, 1, 5; 3, Y, 5, 10";
echo $data;
$ret = array_map (
function ($_) {return explode (', ', $_);},
explode (';', $data)
);
我得到以下多维数组
Array
(
[0] => Array
(
[0] => 1
[1] => AA
[2] => 6
[3] => 10
)
[1] => Array
(
[0] => 1
[1] => Z
[2] => 1
[3] => 5
)
[2] => Array
(
[0] => 2
[1] => AE
[2] => 1
[3] => 5
)
[3] => Array
(
[0] => 2
[1] => AF
[2] => 6
[3] => 10
)
[4] => Array
(
[0] => 3
[1] => X
[2] => 1
[3] => 5
)
[5] => Array
(
[0] => 3
[1] => Y
[2] => 5
[3] => 10
)
)
我想以一个像这样的多维数组结尾:
Array
(
[0] => Array
(
[0] => 1
[1] => Array
(
[0] => Z
[1] => 1
[2] => 5
)
[2] => Array
(
[0] => AA
[1] => 6
[2] => 10
)
)
[1] => Array
(
[0] => 2
[1] => Array
(
[1] => AE
[2] => 1
[3] => 5
)
[2] => Array
(
[1] => AF
[2] => 6
[3] => 10
)
)
[2] => Array
(
[0] => 3
[1] => Array
(
[1] => X
[2] => 1
[3] => 5
)
[2] => Array
(
[1] => Y
[2] => 6
[3] => 10
)
)
)
我不知道什么是获得此结果的最佳方法,也不知道没有太复杂的操作是否有可能。获得最终结果的最佳方法是什么?我应该在“原始”多维数组上工作还是从一开始就从字符串开始工作?
合并相同的数组 Group
首先,我要合并以相同Group
值开头的子字符串。然后,每个字符串的其余部分将成为新创建的数组内的另一个数组。我认为我可以通过解析初始数组(或者字符串本身?)并将结果推入新的数组,同时合并数据来做到这一点。在我的示例中,已经对现在分为三个数组的六个起始数组进行了处理。
使用From
和To
值排序
将具有相同Group
值的子字符串组合到数组中之后,我想对这些数组进行排序,以便To
子数组的From
值始终小于下一个数组的值。初始字符串始终使用以下规则生成:
From
和这样的To
价值:1,5 - 4,7
。这将是两种1,4 - 5,7
或1,5 - 6,7
1,3 - 5,7
From
和To
值可以相同。这样就可以得到:1,4 - 5,5 - 6,7
这就是为什么1, AA, 6, 10; 1, Z, 1, 5;
要Z, 1, 5
遵循的原因AA, 6, 10
。是否有一个PHP函数可以进行这种排序(通过将值与另一个键进行比较)还是我应该创建自己的函数?
另外,如果您认为我应该完全改变我想做的方式(使用多维数组...),并且您有一些想法,请继续分享。我也在这里学习做事的新方法。
有关数据库结构的版本
如@deceze所述,在我的SQL查询期间以不同的方式构造初始字符串可能会更容易。我已经尝试过了,但是我可能不够熟练,无法得到想要的东西。我的数据库如下所示:数据库结构如您所见,所有行均由MasterID链接。这是因为我正在对多个表进行1到n查询。到目前为止,我的查询看起来像这样(我从中删除了所有不必要的内容):
SELECT s.MasterID,
GROUP_CONCAT(CONCAT( CONCAT( CONCAT( CONCAT( CONCAT(
s2d.Group, ', '),
s2d.Section, ', '),
s2d.From),', '),
s2d.To) SEPARATOR '; ') AS Concatstuff,
FROM table1 AS s
JOIN table2 AS s2d
ON s2d.MasterID = s.MasterID
WHERE MasterID = $MasterID (A PHP variable)
由于1对N的关系,我不知道如何使它与众不同。也许我可以使其更简单,并执行两个查询而不是一个查询。在第一个查询中,我从table1获取信息,在第二个查询中,我从table2获取信息。但是,如果您知道仅通过一个查询即可完成所有操作的方法,那么我很想学习如何做到这一点!
我建议在进行许多PHP更改之前修改您的MySQL查询。
大量的concat将会变得非常庞大,最终您甚至可能需要调整MySQL的配置设置,GROUP_CONCAT()
因为它会在一定长度后截断。
取而代之的是,我们可以使用来将GROUP_CONCAT()
and和group专门保留在单个masterid / group组合上GROUP BY
。此外,GROUP_CONCAT()
具有ORDER BY
应解决排序问题的属性:
SELECT
s.MasterID,
s2d.`group`,
GROUP_CONCAT(
s2d.`section`, ',', s2d.`from`, ',', s2d.`to`
ORDER BY `from`, `to`
SEPARATOR ';'
) AS Concatstuff
FROM
table1 AS s
JOIN table2 AS s2d
ON s2d.MasterID = s.MasterID
GROUP BY
s.MasterID, s2d.`group`
WHERE
s.MasterID = $MasterID;
这应该给我们提供类似于以下内容的数据:
MasterID group Concatstuff
2 1 z,1,5;aa,6,10
2 2 ae,1,5;af,6,10
2 3 x,1,5;y,6,10
假设您已从数据库中检索到此数据并将其存储在名为的数组中$results
,我们可以像下面这样迭代它:
$final_groups = array();
foreach ($results as $group) {
// your original `array_map()` logic:
$split_group = array_map(function($_) {
return explode(',', $_);
},
explode(';', $group['Concatstuff'])
);
// ... any other processing you want to do
// store the results:
$final_groups[$group['group']] = $split_group;
}
注意:明确回答您的问题
有没有可以执行这种排序的PHP函数
是的usort()
:
function sort_group($a, $b) {
// [1] = 'from'
// [2] = 'to'
if ($a[1] == $b[1]) {
if ($a[2] == $b[2]) {
return 0;
}
return ($a[2] < $b[2]) ? -1 : 1;
}
return ($a[1] < $b[1]) ? -1 : 1;
}
usort($split_group, 'sort_group');
您可以自定义其中的比较逻辑sort_group()
以匹配您想要的任何内容。上面,我同时对它们 from
和to
=]进行排序
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句