合并具有不同列的表的搜索结果并按日期排序

时间:2013-07-01 03:35:30

标签: php mysql arrays sorting merge

我正在尝试使用一个输出构建三个差异日志表的搜索结果。此输出必须按“时间”排序,并在foreach循环中回显。

  1. id | record-id | user_id |时间|部门|信息

  2. id | user_id | ip |时间|路径|信息|消息|水平

  3. id | req_id |用户|时间|信息|类型| IP

  4. 这三个结果会有所不同,几乎无法比较......

    问题是,在哪里以及如何合并结果...我不认为我只用一个查询来处理这个问题,或者? JOIN(没有参考)和UNION(不同的colums数)可能是错误的选择?

    如果没有其他选项,我可以进行3次查询并合并结果数组

    function cmp($a, $b) {
      if ($a['time'] == $b['time']) {
        return 0;
      }
    
      return ($a['time'] < $b['time']) ? -1 : 1;
    }
    
    $new_arr = array_merge($result1, $result2, $result3);
    uasort($new_arr, 'cmp'); 
    

2 个答案:

答案 0 :(得分:1)

只要您“拉伸”不平衡列的结果,就可以使用联合,例如

SELECT 'table1' AS source, record_id, user_id, time, sector, path
UNION ALL
SELECT 'table2', user_id, null, null, ip, etc....
UNION ALL
SELECT 'table3', null, req_id, null, null, ip, etc...

基本上对于三个表之间常见的任何字段,或者至少是类型兼容的字段,您可以在该字段的结果中使用特定列。对于一个表中不匹配/类型不兼容的字段,只需在其他查询中选择NULL作为“匹配”值。

但是,这会使您的客户端逻辑变得更加复杂,因此您最好只是咬住子弹并运行3个不同的查询。在某些时候,在客户端中必须进行额外的处理以再次分离出相关数据时,触发单个联合查询的次要效率提升超过了。

答案 1 :(得分:1)

一种可能的解决方案是使用UNION ALLCONCAT_WS()将结果集统一为固定数量的列(下例中为5)。然后迭代结果集时,php中的explode() details列值。

SELECT 1 source, id, record_id id2, time, CONCAT_WS('|', user_id, sector, info) details
  FROM table1
 UNION ALL
SELECT 2, id, user_id, time, CONCAT_WS('|', ip, path, info, message, level)
  FROM table2
 UNION ALL
SELECT 3, id, req_id, time, CONCAT_WS('|', user, info, type, ip)
  FROM table3
 ORDER BY time DESC, source, id, id2

示例输出:

| SOURCE | ID |  ID2 |                TIME |                                                              DETAILS |
-------------------------------------------------------------------------------------------------------------------
|      1 | 11 |  111 | 2013-06-30 16:00:00 |                                              12|sector1|info details |
|      2 | 12 |   13 | 2013-06-30 15:00:00 | 10.10.10.1|/your/path/some/where|info details|message details|level1 |
|      3 | 13 | 1024 | 2013-06-30 12:00:00 |                              user1|info details|type info|10.10.10.2 |

这是 SQLFiddle dmeo