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

时间:2014-12-22 16:23:01

标签: php mysql arrays pdo

我已经尝试使用谷歌搜索来解决这个问题,但无济于事。这是我的问题......

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

这是我的例子。我有以下表格

家长(地点) 地址(地址) 电话(电话) 地理数据(地理数据)

当我提取数据时,每个表中只有一行除了手机。可能会列出2或3个电话号码。除了我的查询之外,所有功能都很好,每个电话线都有多次列出相关子数据的父数据。当我得到阵列时,我想到了两种方法来处理它......但我不确定。

1)循环数组并将当前键与前一个键进行比较。如果不同,关闭旧的div,打印新的。如果没有,请将新子项添加到现有div。对于这样一个简单的任务来说,这似乎有些过分,考虑到其他东西可用的强大功能,它看起来有点原始。

2)我玩过array_map和array_unique。结合两者,我可以得到独特的钥匙。这里的问题是,一旦我有了唯一的值,我就不确定如何抓住相应的子节点并创建一个新的数组,其子节点正确地分组在父节点下。

有什么我想念的吗?我没有任何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

1 个答案:

答案 0 :(得分:0)

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

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 explainedGrouping and why it's important :)