2016-06-14 90 views
0

我有以下查询;SELF-JOIN丢弃true CROSS JOIN行

我得到的是门票信息。我使用自联接,以获得请求者和同一行中的受让人:

SELECT z.id AS TICKET, z.name AS Subject, reqs.name AS Requester, techs.name AS Assignee, 
     e.name AS Entity,DATE_FORMAT(tt.date,'%y%-%m%-%d') AS DATE, 
     DATE_FORMAT(tt.date,'%T') AS HOUR, 
     CASE WHEN z.priority = 6 THEN 'Mayor' WHEN z.priority = 5 THEN 'Muy urgente' WHEN z.priority = 4 THEN 'Urgente'WHEN z.priority = 3 THEN 'Mediana' WHEN z.priority = 2 THEN 'Baja' WHEN z.priority =1 THEN 'Muy baja' END AS Priority, 
     c.name AS Category, i.name AS Department 
FROM glpi_tickets_users tureq 
JOIN glpi_tickets_users tutech ON tureq.tickets_id = tutech.tickets_id 
JOIN glpi_users AS reqs ON tureq.users_id = reqs.id 
JOIN glpi_users AS techs ON tutech.users_id = techs.id 
JOIN glpi_tickets z ON z.id = tureq.tickets_id 
LEFT OUTER JOIN glpi_tickettasks tt ON z.id = tt.tickets_id 
LEFT JOIN glpi_itilcategories i ON z.itilcategories_id = i.id 
LEFT JOIN glpi_usercategories c ON c.id = reqs.usercategories_id 
INNER JOIN glpi_entities e ON z.entities_id = e.id 
WHERE (tureq.id < tutech.id AND tureq.type < tutech.type) OR 
     (tureq.id < tutech.id AND tureq.users_id = tutech.users_id) OR 
     (tureq.id = tutech.id AND tureq.users_id = tutech.users_id) 

的问题是,我得到类似的东西:

1 Report jdoe  jdoe  Development 16-06-07 11:56:17  Mediana Software Mkt 
1 Report jdoe  fwilson  Development 16-06-07 11:56:17  Mediana Software MKt 
1 Report fwilson  fwilson  Development 16-06-07 11:56:17  Mediana Software Mkt 
2 Task11 gwilliams gwilliams Ops   16-06-08 12:00:00  ALTA Hardware Def 
3 Task12 gwilliams gwilliams Ops   16-06-08 12:01:00  ALTA Hardware Def 

我不想第一和第三排做因为是CROSS JOIN结果。第二行是好的,因为jdoe是请求者,fwilson是受让人。

问题是,有时候请求者和受让人是相同的,例如:他为自己将要执行的任务创建票据。例如,第4行和第5行都可以。

所以,我应该怎么做才能让那些不同的情况有差别,即:我需要包括:

tureq.id = tech.id AND req.users_id = tech.users.id

但如果已经存在
tureq.id = tech.id AND req.users_id <> tech.users_id

更新

主要问题是用户可以给自己分配一张票:

SELECT * from glpi_tickets_users WHERE type = 2 GROUP BY tickets_id HAVING COUNT(users_id)<2 limit 3; 
+----+------------+----------+------+------------------+-------------------+ 
| id | tickets_id | users_id | type | use_notification | alternative_email | 
+----+------------+----------+------+------------------+-------------------+ 
| 1 |   2 |  12 | 2 |    1 | NULL    | 
| 3 |   6 |  13 | 2 |    1 | NULL    | 
| 7 |   8 |  14 | 2 |    1 | NULL    | 
+----+------------+----------+------+------------------+-------------------+ 

更新2:

这是一个人的错。问题实际上不是关于自我分配的票证。相反,有些票据不是Requester或Requester,但仍未分配任何解析器。 我找到了

+0

请阅读有关如何创建一个MCVE([MCVE])。一个包含9个表的查询不太可能是最小的;如果是的话,会有解释你如何证明它很少。 –

+0

我想你需要在加入glpi_tickets_users之前先旋转glip_tickets_users,这样你就不会有多个连接给你交叉连接,就像结果一样。 – xQbert

+1

因此,每张票可以有多个用户,它就像一个按类型编号的链?即类型1是受让人类型2的申请人,类型2本身是否是受让人类型3的申请人?至少这是我理解你的查询的方式。您能否在票证中至少显示三位人员的样本数据以及期望的结果? –

回答

3

由于您感兴趣的每张票有两种类型,您可以简单地选择相应的记录,以便获得每张票的请求者和受让人。

select 
    t.id as ticket, 
    t.name as subject, 
    requester.name as requester, 
    assignee.name as assignee, 
    e.name as entity, 
    date_format(tt.date,'%y%-%m%-%d') as date, 
    date_format(tt.date,'%T') as hour, 
    case t.priority 
    when 6 then 'Mayor' 
    when 5 then 'Muy urgente' 
    when 4 then 'Urgente' 
    when 3 then 'Mediana' 
    when 2 then 'Baja' 
    when 1 then 'Muy baja' 
    end as priority, 
    uc.name as category, 
    ic.name as department 
from glpi_tickets t 
join glpi_entities e on e.id = t.entities_id 
join 
(
    select tu.tickets_id, u.name, u.usercategories_id 
    from glpi_tickets_users tu 
    join glpi_users u on u.id = users_id 
    where tu.type = 1 
) requester on requester.tickets_id = t.id 
join 
(
    select tu.tickets_id, u.name 
    from glpi_tickets_users tu 
    join glpi_users u on u.id = users_id 
    where tu.type = 2 
) assignee on assignee.tickets_id = t.id 
left join glpi_itilcategories ic on ic.id = t.itilcategories_id 
left join glpi_usercategories uc on uc.id = requester.usercategories_id; 
left outer join glpi_tickettasks tt on tt.tickets_id = t.id 

我唯一想知道的是:每张票可以有多个票务任务。那么你想怎么做?您的结果中每个票务任务有一行?这是查询所要做的。只是,看起来很奇怪,除了日期之外,结果行不包含有关任务的任何信息,因此您可能有许多具有相同数据的行,只有不同的日期。所以也许,你宁愿要每票的第一个或最后一个日期。为了让每票的最后一天,你会在与查询替换最后一行:

left outer join 
(
    select tickets_id, max(date) as date 
    from glpi_tickettasks 
    group by tickets_id 
) tt on tt.tickets_id = t.id 

而且你可能要添加ORDER BY条款。

+1

如果你添加了需求(例如'and requester.type = 1' to join statement),你不需要子查询 – Hogan

+0

@ thorsten-kettner我需要在每个任务中总结小时数,这是一个很好的方法,但,主要的问题是什么时候是一个“自我分配”票证的用户类型是相同的。 – sebelk

+0

我已经添加到第一个子查询'或tu.type = 2 GROUP BY tu.tickets_id HAVING COUNT(tu。 id)= 1',但它也不会工作 – sebelk

0

你需要添加更多的预选赛到你的加入,例如

JOIN glpi_tickets_users tutech ON tureq.tickets_id = tutech.tickets_id and tutech.type = 2