【发布时间】:2020-08-09 22:11:19
【问题描述】:
我正在为我的公司开发一个 HelpDesk 系统,其中有一系列相关表格,如下图所示:
主表是tickets,里面存放了ticket的基本数据,包括它的作者id_pers_empleado。
最重要的表格是tickets_asignaciones,您可以在其中指明工单是分配给员工(我们将在此表格中称为代理)id_agente 还是分配给团队id_equipo。
团队在tickets_equipos 表中定义,组成每个团队的代理在tickets_equipos_agentes 表中指示,该表关联tickets_equipos 和empleados 表。
我需要的是一个查询,可以让我得到所有的票...
- 作者是某个工人 X (
WHERE tickets.id_pers_empleado = X)。 - 或者他们被直接分配给那个工人 X (
WHERE tickets_asignaciones.id_pers_empleado = X)。 - 或者将他们分配到所述工人 X 所属的团队:
WHERE
tickets.id_pers_empleado IN (
SELECT
tickets_equipos_agentes.id_pers_empleado
FROM
tickets_equipos_agentes
WHERE
tickets_asignaciones.id_equipo = tickets_equipos_agentes.id_pers_empleado
)
AND
tickets.id_pers_empleado = X
(我不确定以上是否正确,可能不是)。
我可以通过使用 PHP 和 foreach 循环执行多个独立查询来做到这一点,但我不想让服务器因如此多的请求而超载,我需要一个能够同时完成所有工作的查询。
我已经以不同的方式尝试了很多 JOINS,现在我头晕目眩,卡住了。我找不到正确编写查询的正确方法。另外,我不知道是否应该以某种方式使用子查询来实现我想要做的事情。
我认为问题不在于表格的关系或布局,而在于我对此类复杂查询缺乏了解。
有人对如何解决它有任何想法吗?谢谢。
我将放置我正在使用的小数据集。
门票表
这里id_pers_empleado是工单的作者,即创建记录的用户。
+-------------+---------------------+----------------------------------------------+---------+------------------+
| id | fecha | titulo | id_tipo | id_pers_empleado |
+=============+=====================+==============================================+=========+==================+
| 00000000001 | 2020/07/26 08:24:40 | Ticket de autoría propia (sin asignación) | 01 | 00000005 |
+-------------+---------------------+----------------------------------------------+---------+------------------+
| 00000000002 | 2020/08/08 16:32:43 | Ticket asignado a un solo agente | 02 | 00000011 |
+-------------+---------------------+----------------------------------------------+---------+------------------+
| 00000000003 | 2020/08/08 19:19:38 | Ticket asignado a un equipo | 02 | 00000012 |
+-------------+---------------------+----------------------------------------------+---------+------------------+
| 00000000004 | 2020/08/08 19:24:16 | Ticket asignado a varios agentes | 02 | 00000004 |
+-------------+---------------------+----------------------------------------------+---------+------------------+
| 00000000005 | 2020/08/08 19:27:21 | Ticket asignado a un equipo y varios agentes | 01 | 00000001 |
+-------------+---------------------+----------------------------------------------+---------+------------------+
TICKETS_ASIGNACIONES 表
在此表中,id_pers_empleado 是分配票证的人,id_agente 是分配票证的人。有可能id_agente为空,此时必须填写id_equipo。
这里id_pers_empleado 不能为空,因为它试图知道谁是分配/升级票证的人。特定工单也可能没有任何分配,因为该工单是新工单并且尚未决定应将其分配给谁,或者因为它是信息工单并且不需要任何代理干预。
+-------------+------------------+-----------+-----------+
| id_ticket | id_pers_empleado | id_equipo | id_agente |
+=============+==================+===========+===========+
| 00000000002 | 00000011 | | 00000005 |
+-------------+------------------+-----------+-----------+
| 00000000003 | 00000002 | 02 | |
+-------------+------------------+-----------+-----------+
| 00000000004 | 00000003 | | 00000003 |
+-------------+------------------+-----------+-----------+
| 00000000004 | 00000002 | | 00000002 |
+-------------+------------------+-----------+-----------+
| 00000000005 | 00000001 | 04 | |
+-------------+------------------+-----------+-----------+
| 00000000005 | 00000001 | | 00000001 |
+-------------+------------------+-----------+-----------+
| 00000000005 | 00000001 | | 00000004 |
+-------------+------------------+-----------+-----------+
TICKETS_EQUIPOS 表
它是tickets_asignaciones和 tickets_equipos_agentes之间的桥梁,它还会保存其他数据,例如图标,颜色,以及谁是团队负责人,但它们不相关,因此我没有包含它们。
+-------------+--------------+
| id | nombre |
+=============+==============+
| 00000000001 | Contabilidad |
+-------------+--------------+
| 00000000002 | RRHH |
+-------------+--------------+
| 00000000003 | Calidad |
+-------------+--------------+
| 00000000004 | Técnico |
+-------------+--------------+
TICKETS_EQUIPOS_AGENTES 表
这里的id_pers_empleado 是上表中属于某个团队的工人。同一个工作人员/代理可以同时在多个团队中。
+-------------+------------------+
| id_equipo | id_pers_empleado |
+=============+==================+
| 00000000001 | 00000001 |
+-------------+------------------+
| 00000000001 | 00000098 |
+-------------+------------------+
| 00000000002 | 00000006 |
+-------------+------------------+
| 00000000002 | 00000007 |
+-------------+------------------+
| 00000000002 | 00000008 |
+-------------+------------------+
| 00000000003 | 00000001 |
+-------------+------------------+
| 00000000003 | 00000011 |
+-------------+------------------+
| 00000000003 | 00000098 |
+-------------+------------------+
| 00000000004 | 00000005 |
+-------------+------------------+
| 00000000004 | 00000034 |
+-------------+------------------+
到目前为止的近似值
到目前为止,我发现显示我正在寻找的结果的最佳方式是:
SELECT
t1.id,
t1.id_pers_empleado autor,
t1.titulo,
t2.id_agente,
t2.id_equipo,
t3.nombre nombreEquipo
FROM
tickets t1
LEFT JOIN
tickets_asignaciones t2 ON t1.id = t2.id_ticket
LEFT JOIN
tickets_equipos t3 ON t2.id_equipo = t3.id
WHERE
t1.id_pers_empleado = 5
OR
t2.id_agente = 5
OR
t1.id_pers_empleado IN (
SELECT
id_pers_empleado
FROM
tickets_equipos_agentes t4
LEFT JOIN tickets_equipos t5 ON t4.id_equipo = t5.id
WHERE t4.id_equipo = t3.id
)
GROUP BY t1.id
ORDER BY t1.id
运算结果集是这样的:
+-------------+----------+----------------------------------------------+-----------+-----------+--------------+
| id_ticket | autor | titulo | id_agente | id_equipo | nombreEquipo |
+=============+==========+==============================================+===========+===========+==============+
| 00000000001 | 00000005 | Ticket de autoría propia (sin asignación) | | | |
+-------------+----------+----------------------------------------------+-----------+-----------+--------------+
| 00000000002 | 00000011 | Ticket asignado a un solo agente | 5 | | |
+-------------+----------+----------------------------------------------+-----------+-----------+--------------+
| 00000000005 | 00000001 | Ticket asignado a un equipo y varios agentes | | 4 | Técnico |
+-------------+----------+----------------------------------------------+-----------+-----------+--------------+
到目前为止,它似乎有效,但我不知道我是否以最好的方式做到这一点,或者有什么可以从查询中改进的。还有一些情况我看不到正确的结果。我快疯了。
【问题讨论】:
-
参见meta.stackoverflow.com/questions/333952/…,并注意
3的可读性不低于0000000000003