2016-06-14 88 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