Sql 自连接丢弃真正的交叉连接行
我有以下疑问 我得到的是门票信息。我使用self-join获取同一行中的请求者和受让人:Sql 自连接丢弃真正的交叉连接行,sql,mariadb,self-join,cross-join,Sql,Mariadb,Self Join,Cross Join,我有以下疑问 我得到的是门票信息。我使用self-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,
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)
我不想要第一行和第三行,因为这是交叉连接的结果。第二行可以,因为jdoe是请求者,fwilson是受让者
问题是,有时请求者和受让者是相同的,例如:他为自己将要完成的任务创建了一个票证。例如,第4行和第5行是可以的
那么,我应该如何做才能使这些不同的情况有所不同,即:我需要包括:
tureq.id=tech.id和req.users\u id=tech.users.id
但如果已经存在,则不存在tureq.id=tech.id和req.users\u id tech.users\u 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 |
+----+------------+----------+------+------------------+-------------------+
SELECT*from glpi\u tickets\u users,type=2 groupby tickets\u id have COUNT(users\u id)由于您感兴趣的每张票据始终有两种类型,您只需选择相应的记录,即可获得每张票据的请求者和受让者
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
子句。由于您感兴趣的每张票据都有两种类型,您只需选择相应的记录,即可获得每张票据的请求者和受让者
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
子句。例如,您需要向联接添加更多限定符
JOIN glpi_tickets_users tutech ON tureq.tickets_id = tutech.tickets_id and tutech.type = 2
例如,您需要向联接添加更多限定符
JOIN glpi_tickets_users tutech ON tureq.tickets_id = tutech.tickets_id and tutech.type = 2
请阅读如何创建MCVE()。一个包含9个表的查询不太可能是最小的;如果是的话,会有解释说明你是如何证明它是最小的。我认为你需要在加入glpi_tickets_用户之前,先关注glpi_tickets_用户,这样你就不会有多个连接给你交叉连接的结果。所以每个ticket可以有很多用户,就像一个按类型编号的链?即类型1是受让人类型2的请求者,类型2本身是受让人类型3的请求者?至少我是这样理解你的问题的。您能否显示一张票证中至少有三个人的样本数据以及所需的结果?@thorsten kettner是的,每张票证可以有多个用户。类型1是请求者,类型2是受让人。但碰巧的是,同一个用户可以打开一张票证并分配给自己,这是正确的。但我想排除交叉连接。只有类型1和类型2?没有其他类型的吗?如果一个用户分配给自己,那么同一个用户有两个条目,一个是类型1,一个是类型2?每个票证总是有两个条目,一个是类型1,一个是类型2?请阅读如何创建MCVE()。一个包含9个表的查询不太可能是最小的;如果是的话,会有解释说明你是如何证明它是最小的。我认为你需要在加入glpi_tickets_用户之前,先关注glpi_tickets_用户,这样你就不会有多个连接给你交叉连接的结果。所以每个ticket可以有很多用户,就像一个按类型编号的链?即类型1是受让人类型2的请求者,类型2本身是受让人类型3的请求者?至少我是这样理解你的问题的。您能否显示一张票证中至少有三个人的样本数据以及所需的结果?@thorsten kettner是的,每张票证可以有多个用户。类型1是请求者,类型2是受让人。但碰巧的是,同一个用户可以打开一张票证并分配给自己,这是正确的。但我想排除交叉连接。只有类型1和类型2?没有其他类型的吗?如果一个用户分配给自己,那么同一个用户有两个条目,一个是类型1,一个是类型2?每个票证总是有两个条目,一个是类型1,一个是类型2?如果将需求(例如和requester.type=1
添加到联接中,则不需要子查询statement@thorsten-kettner我需要对每个任务的小时数求和。这是一个很好的方法,但是,主要问题是什么时候是“自行分配的”ticket用户类型相同。我已通过tu.tickets\u id添加到第一个子查询或tu.type=2组,其中tu.tickets\u id具有COUNT(tu.id)=1
但它也不起作用。@Hogan:你是对的。我认为通过子查询,哪些数据属于请求者,哪些数据属于受让者,变得非常可读,但这没有多大区别,许多人可能更喜欢你建议的简单联接。@sebelk:所以你没有正确回答我的问题。问题又来了:“如果一个用户分配给自己,同一个用户有两个条目,一个是类型1,一个是类型2?”现在你说情况并非如此,那么是否有两个条目是类型1?或者两个条目是类型2?或者只有一个条目?(无论如何,这会使查询更加复杂,因为你没有像我想的那样一致地存储数据。)如果将需求(例如和requester.type=1
添加到联接,则不需要子查询statement@thors