2015-02-05 62 views
0

表sca_ticket_thread存储状态更改日期。我试图计算两个状态之间的平均时间差。 “已创建”列存储状态更改的日期,“正文”列存储状态更改。计算同一张表上的行之间的平均时间差

SELECT AVG(DateDiff((SELECT created FROM 
(SELECT created 
FROM sca_ticket_thread 
WHERE body = 'AchangetoB' 
OR body = 'BchangetoC' 
GROUP BY ticket_id 
HAVING count(*) > 1) 
as subquery), 
(SELECT created 
FROM sca_ticket_thread 
WHERE body = 'BchangetoC' 
ORDER BY ticket_id))) 
FROM sca_ticket_thread 

我收到的错误是:#1242 - 子查询返回多个1行

我(在概念上,一点点)了解到,子查询不能返回超过1行。我已经考虑加入一张表作为一种可能的解决方案,但我认为这不是正确的道路。

最后,我想生成从A到B的平均状态的变化,B到C到d等

ID | STATUS | DATE 
-------------------------- 
1 | Status A | 02/01/2015 
1 | Status A | 02/02/2015 
2 | Status B | 02/03/2015 
+0

运行的两个子查询,看看他们返回的内容。我无法回想一下子查询可以返回多少行的限制。例如:'SELECT * FROM X WHERE x_id IN(SELECT x_id FROM X where x_value LIKE'foo%');'完全有效,子查询可以返回多行。有些选项可以实现你想要的功能,包括:LIMIT,GROUP,MAX,MIN等等。 – nevets1219

+0

第一个select语句返回24行,第二个是17.这是问题吗? – Duke

+0

是的。 DateDiff只需要两个参数。您需要过滤掉其他行以获得您想要的。此外,您应该确保多个'AchangetoB'和'BchangetoC'是有效的,如果不是,您可能会收紧架构以防止出现这种情况。 – nevets1219

回答

0

让我们来看看你的最新查询:

SELECT AVG(DateDiff(
    (SELECT created FROM (
    SELECT ticket_id, created, body 
    FROM sca_ticket_thread 
    WHERE body = 'AchangetoB' OR body = 'BchangetoC' 
    GROUP BY 1 
    HAVING count(*) > 1) as subquery), 
    (SELECT created FROM sca_ticket_thread WHERE body = 'BchangetoC' ORDER BY ticket_id))) 
FROM sca_ticket_thread 

几个问题脱颖而出:

  1. 您的子查询正在返回多个列(ticket_id,created和body),但实际上并没有使用他们所以你应该检索created。不是一个实际的问题,但它确实会影响性能,所以你应该牢记这一点。
  2. 我不知道GROUP BY 1,但它是有效的(每天学习新东西)。在这种情况下,它基本上意味着GROUP BY ticket_id(您的SELECT中的第一列)。我不认为这是有效的,因为您正在选择3列,但只是按1列分组。
  3. 我想你只是试图将响应限制在HAVING的一行上,但在这种情况下,这意味着返回的结果给我的结果,其ticket_id出现多次。

我的MySQL有点生疏,但我认为是对的。

我觉得我很困惑,但你可能需要做的不是使用子查询,而是使用分组和/或连接。也许您可以使用您在查询中提供的模式发布简短示例。诸如http://sqlfiddle.com/对于查看问题和自己调试的人来说非常方便。

还有一些其他的答案可能会有所帮助: