2

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

  1. 桌子

    编号 | 记录ID | 用户 ID | 时间 | 部门 | 信息

  2. 桌子

    编号 | 用户 ID | 知识产权 | 时间 | 路径 | 信息 | 留言 | 等级

  3. 桌子

    编号 | req_id | 用户 | 时间 | 信息 | 类型 | ip

这三个结果都是不同的,几乎没有可比性......

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

如果没有其他选项,我可以进行 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'); 
4

2 回答 2

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 个不同的查询。在某些时候,启动单个联合查询所带来的微小效率收益被您必须在客户端中进行的额外处理以再次分离出相关数据所抵消。

于 2013-07-01T04:09:48.410 回答
1

一种可能的解决方案是使用UNION ALL并将CONCAT_WS()您的结果集统一为固定数量的列(在下面的示例中为 5)。然后explode() details在遍历结果集时在 php 中列值。

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

样本输出:

| 来源 | 身份证 | ID2 | 时间 | 详情 |
-------------------------------------------------- -------------------------------------------------- ---------------
| 1 | 11 | 111 | 2013-06-30 16:00:00 | 12|sector1|信息详情 |
| 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 | 用户 1|信息详细信息|类型信息|10.10.10.2 |

这是SQLFiddle dmeo

于 2013-07-01T04:14:58.790 回答