PHP - 解析具有多个父级的数组并组合子级

标签 php mysql arrays pdo

我尝试用谷歌搜索来解决这个问题,但没有成功。这是我的问题...

我运行一个查询来从 4 或 5 个表中提取数据。它工作得很好,但如果有多个子项,则父项将作为具有多个子数组的数组的一部分返回。我想解析数组并检索相关数据,但我不确定最好的方法。我知道 PHP 有一个强大的预定义函数子集来处理数组和 MySQL,所以我不确定是否有我遗漏的东西。另外,我正在使用 PDO,以防它产生影响。

这是我的例子。我有下表

父级(位置) 地址(地址) 电话(电话) 地理数据(geodata)

当我提取数据时,除了电话之外,每个表中应该只有一行。可能会列出 2 或 3 个电话号码。除了我的查询之外,一切都很好,然后为每条电话线多次列出了父数据和关联的子数据。当我得到数组时,我想到了两种处理它的方法......但我不确定。

1) 循环数组并将当前键与前一个键进行比较。如果不同,关闭旧的 div,打印新的。如果没有,请将新子元素添加到现有 div 中。对于这样一个简单的任务来说,这似乎有点矫枉过正,而且考虑到可用于其他事情的强大功能,这似乎有点原始。

2) 我玩过一些 array_map 和 array_unique 。通过两者的结合,我可以得到唯一的 key 。这里的问题是,一旦我有了唯一值,我不太确定如何获取相应的子项并创建一个新数组,其中子项正确分组在父项下。

我有什么遗漏的吗?我没有任何 PHP 可以发布,但我将发布我的查询,以防万一我也可以在那里提供帮助。另外,我并不是在寻找任何人在这里给我代码 - 只要朝正确的方向轻推一下就很好了。

提前致谢!!

SELECT 04_rest_00_locations.Name, 
04_rest_00_locations.Description, 
04_rest_00_locations.RNID,
04_rest_01_addresses.Add1,
04_rest_01_addresses.Add2,
02_driver_geodata.primary_city,
02_driver_geodata.state,
02_driver_geodata.zip,
04_rest_01_phones.AreaCode,
04_rest_01_phones.Prefix,
04_rest_01_phones.LineNum
FROM 04_rest_00_locations 
LEFT JOIN 04_rest_01_addresses
ON 04_rest_00_locations.id = 04_rest_01_addresses.RestID
AND GroupID 
IN (SELECT 04_rest_00_locations.GroupID 
    FROM 04_rest_00_locations 
    WHERE RestID = $RestID)
LEFT JOIN 04_rest_01_phones
ON 04_rest_00_locations.id = 04_rest_01_phones.RestID
AND 04_rest_01_phones.active = 1
AND 04_rest_01_phones.IsPublic = 1
AND 04_rest_01_phones.PhoneType = 1
LEFT JOIN 02_driver_geodata
ON 04_rest_01_addresses.CSZID = 02_driver_geodata.id
AND 04_rest_01_addresses.active = 1
AND 04_rest_01_addresses.AddType = 1
WHERE 04_rest_00_locations.active = 1
AND 04_rest_00_locations.Published = 1
<小时/>

更新 - 我已将查询更改为以下内容,效果很好(谢谢),但它只返回一行。我错过了什么?再次感谢!!

SELECT 04_rest_00_locations.Name, 
04_rest_00_locations.Description,
04_rest_00_locations.RNID,
04_rest_01_addresses.Add1, 
04_rest_01_addresses.Add2,
02_driver_geodata.primary_city, 
02_driver_geodata.state, 
02_driver_geodata.zip, 
GROUP_CONCAT(04_rest_01_phones.PhoneType, ";",  04_rest_01_phones.AreaCode, 04_rest_01_phones.Prefix, 04_rest_01_phones.LineNum) AS Phones
    FROM 04_rest_00_locations 
    LEFT JOIN 04_rest_01_addresses
    ON 04_rest_00_locations.id = 04_rest_01_addresses.RestID
    AND GroupID 
    IN (SELECT 04_rest_00_locations.GroupID 
        FROM 04_rest_00_locations 
        WHERE RestID = 1)
    LEFT JOIN 04_rest_01_phones
    ON 04_rest_00_locations.id = 04_rest_01_phones.RestID
    AND 04_rest_01_phones.active = 1
    AND 04_rest_01_phones.IsPublic = 1
    LEFT JOIN 02_driver_geodata
    ON 04_rest_01_addresses.CSZID = 02_driver_geodata.id
    AND 04_rest_01_addresses.active = 1
    AND 04_rest_01_addresses.AddType = 1
    WHERE 04_rest_00_locations.active = 1
    AND 04_rest_00_locations.Published = 1

最佳答案

抱歉!愚蠢的我 - 我找到了答案。这是更新后的查询 - 您必须将数据分组在一起才能使其正常工作。

SELECT loc.Name, loc.Description, loc.RNID, addr.Add1, addr.Add2, geo.primary_city, geo.state, geo.zip, GROUP_CONCAT(ph.PhoneType, ";",  ph.AreaCode, ph.Prefix, ph.LineNum) AS Phones
FROM 04_rest_00_locations loc 
LEFT JOIN 04_rest_01_addresses addr
    ON loc.id = addr.RestID
    AND GroupID IN 
    (   SELECT loc.GroupID 
        FROM loc 
        WHERE RestID = 1
    )
LEFT JOIN 04_rest_01_phones ph
    ON loc.id = ph.RestID
    AND ph.active = 1
    AND ph.IsPublic = 1
LEFT JOIN 02_driver_geodata geo
    ON addr.CSZID = geo.id
    AND addr.active = 1
    AND addr.AddType = 1
WHERE loc.active = 1
AND loc.Published = 1
GROUP BY loc.id

以下是我发现的一些确实有帮助的链接。再次感谢大家的帮助!

GROUP_CONCAT explained , Grouping and why it's important :)

关于PHP - 解析具有多个父级的数组并组合子级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27606471/

相关文章:

mysql - PHP循环遍历多个数据库表

jquery - 如何使用Ajax调用MVC4传递两个字符串数组

ruby-on-rails - Rails 方法检测空字符串数组( ["", "",...])为空

php - 将数据库与外部表连接

javascript - 使用 jquery 对话框中的 html 表单更新 mysql 中的数据

PHPMailer 发送消息,但将 CLIENT/SERVER 对话框返回给浏览器

mySQL创建汇总项目列表

python - 索引 Python fetchall()

java - 如何使用 Java 反射将数组写入 XML 文件?

php - 有什么方法可以在站点地图页面上显示 3 个以上的类别? (打开购物车 3)