获取包含子项和条件的父行

时间:2015-07-21 21:42:00

标签: mysql nested parent-child

我有一张名为ticket的表:

ticket (idTicket, title , message , parentTicket, lastdate, status)

状态获得默认值:打开,一旦i(mod)回复设置为回复

我试图获取活动票证意味着打开状态(新创建和最后一个用户回复)

示例:

13 , 'Title 1' , 'msg Title1' , NULL , 'open'
14 , 'Title 2' , 'msg Title2' , NULL , 'open'
15 , 'reply Title 2' , 'reply msg Title2' , 14 , 'replied'
16 , 'Title 3' , 'msg Title3' , NULL ,'open'
17 ,  'reply Title 3' , 'reply msg Title3' , 16 , 'replied' 

通常我应该只列出门票号13

我的2个查询想法但没有运气

1 /

SELECT *
FROM ticket AS parent LEFT JOIN
     ticket AS child 
     ON child.parentTicket = parent.idTicket
WHERE parent.parentTicket IS NULL and child.status ="open"
ORDER BY parent.idTicket, child.idTicket;

2 /

Select t1.idTicket ,t2.parentTicket
from ticket t1 inner join
     ticket t2
     on (t1.idTicket != t2.parentTicket)
where t1.status ="open" and t2.parentTicket is null
Group by idTicket

3 /

Select a.idTicket ,a.titleTicket,a.parentTicket
from ticket a
where not exists (select null from ticket b where a.parentTicket!=b.parentTicket) 
and a.status='open'

1 个答案:

答案 0 :(得分:1)

要返回没有任何子票证的打开的“根”票证,即ticket的{​​{1}}行,NULLparentTicketstatus='open' 1}},并且子票不存在,您可以使用反连接模式:

 SELECT p.*
   FROM ticket p
   LEFT
   JOIN ticket c
     ON c.parentTicket = p.idTicket
  WHERE p.parentTicket IS NULL
    AND p.status = 'open'
    AND c.parentTicket IS NULL

反连接是一个外连接,在WHERE子句中有一个谓词,它排除了匹配的行。这基本上是说获得所有打开的“根”票,以及任何匹配的子行。技巧是最后一个谓词c.parentTicket IS NULL ...任何匹配的子行都保证具有非NULL值(由于JOIN谓词),因此这排除了具有匹配子项的任何行。

这相当于带有NOT EXISTS (subquery)谓词的查询。这可能更容易理解:

 SELECT p.*
   FROM ticket p
  WHERE p.parentTicket IS NULL
    AND p.status = 'open'
    AND NOT EXISTS
        ( SELECT 1
            FROM ticket c
           WHERE c.parentTicket = p.idTicket
        )
 ;

这两个查询都会返回idTicket=13行。

SQL Fiddle demonstration here: http://sqlfiddle.com/#!9/393b7/1

但是......当这些查询返回指定的行,并且足以满足问题中提供的样本数据时,我认为这不符合规范的 complete 。关于“上次用户回复”的问题中有一点,但除此之外,规范相当稀疏。没有示例数据说明应该(并且不应该)返回哪些行。如果有多个回复或对回复的回复,以及回复的状态和作者身份等怎么办?

或者,也许这些查询足够,或者至少足以让你朝着正确的方向前进。