2015-02-05 2 views
0

В таблице sca_ticket_thread хранятся даты изменения статуса. Я пытаюсь вычислить среднюю разницу во времени между двумя статусами. В столбце «created» хранится дата изменения статуса, а в столбце «тело» хранится изменение состояния.Вычисление средних разниц времени между строками в одной таблице

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 ряд

I (концептуально, немного) понимают, что подзапрос не может возвращать более 1 строку. Я задумался о том, чтобы присоединиться к таблице как к возможному решению, но я не думаю, что это правильный путь вперед.

В конце концов, я хотел бы, чтобы произвести среднее изменение состояния от А до Б, В к С к 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, где 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, но в этом случае это означает результаты возврата, которые дают мне результаты, чей билет_ид появляется более одного раза.

Мой MySQL немного ржавый, но я думаю, что это правильно.

Я думаю, что я был в замешательстве, но то, что вам, вероятно, нужно делать, это не использование подзапросов, а использование группировки и/или присоединение. Возможно, вы можете опубликовать краткий пример, используя схему, представленную в вашем запросе. Что-то вроде http://sqlfiddle.com/ было бы очень удобно для людей, которые рассматривали вопрос и для собственной отладки.

Есть несколько других ответов, которые могут быть полезны:

Смежные вопросы