2016-06-14 7 views
0

다음 쿼리가 있습니다.CROSS JOIN 행을 삭제하는 자체 조인

내가 얻는 것은 티켓 정보입니다.

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 

내가 첫 번째와 세 번째 행을 원하지 않는 :

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) 

문제는 내가 그런 일을 얻을 수 있다는 것입니다 : 나는 스터와 같은 행에있는 양수인을 얻기 위해 자기를 조인 사용 CROSS JOIN 결과 때문입니다. jdoe는 리퀘 스터이고 fwilson은 양수인이기 때문에 두 번째 행은 OK입니다.

문제는 요청자와 배정 된 사람이 같은 경우 일 수 있습니다. 즉, 자신이 할 일에 대한 티켓을 만듭니다. 예를 들어, 네 번째와 다섯 번째 행은 OK입니다. 그래서

, 나는 그 뚜렷한 경우에 대한 차이, 즉를 만들기 위해 할 방법 : I을 포함해야합니다

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 :

그것은 인간의 실수였다. 문제는 자체 할당 티켓에 관한 것이 아닙니다. 오히려 그것은 일부 티켓이 리퀘 스터가 아니거나 리퀘 스터를 가지고 있지만 아직 어떤 리졸버가 할당되어 있지 않다는 것입니다. 찾았습니다

+0

조인에 더 한정자를 추가해야합니다. 그 안에 9 개의 테이블이있는 쿼리는 최소화 될 것 같지 않습니다. 그렇다면, 그것이 최소한이라는 것을 어떻게 증명했는지에 대한 설명이있을 것입니다. –

+0

glpi_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

요구 사항을 추가 할 경우 하위 쿼리가 필요하지 않습니다 (예 :'및 requester.type = 1'). 각 작업별로 시간을 합산해야합니다. – Hogan

+0

@ thorsten-kettner 가장 중요한 문제는 "자체 할당 된"티켓이 사용자 유형이 동일한 경우입니다. – sebelk

+0

첫 번째 하위 쿼리'OR tu.type = 2 GROUP BY tu.tickets_id HAVING COUNT (tu. id) = 1'도 작동하지 않을 것입니다. – sebelk

0

당신은 당신이 MCVE ([MCVE]를) 만드는 방법에 대해 읽어 보시기 바랍니다 예를

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