-4
SELECT t1.*
                FROM asterisk t1
                WHERE EXISTS (SELECT * FROM asterisk t2
                              WHERE t2.id <> t1.id
                              AND t2.unique_id = t1.unique_id
                              AND t1.operator_dial = '203'
                              AND t1.event = 'Dial'
                              AND t2.event = 'Bridge'
                              AND NOT EXISTS (SELECT * FROM asterisk t3
                                          WHERE t3.id <> t1.id
                                          AND t2.unique_id = t3.unique_id
                                          AND t1.operator_dial = '203'
                                          AND t3.event = 'Unlink'))
                ORDER BY date DESC
                LIMIT 1

需要帮助以使其快速工作,这可能吗?我的脑袋准备爆炸,试图理解它应该做什么。(表有大约 5k 条记录)该查询的描述是:“看看是否有 Dial 事件,之后是 Bridge 事件,但没有 Unlink 事件”。

4

3 回答 3

1

尝试使用连接而不是存在。

SELECT t1 * 
FROM asterisk t1
INNER JOIN asterisk t2 on t1.id=t2.id
    AND t2.unique_id = t1.unique_id
    AND t1.operator_dial = '203'
    AND t1.event = 'Dial'
    AND t2.event = 'Bridge'
LEFT OUTER JOIN asterisk t3 on t2.unique_id=t3.unique_id
    AND t3.id <> t1.id
    AND t1.operator_dial = '203'
            AND t3.event = 'Unlink'
WHERE t3.id IS NULL
            ORDER BY date DESC
            LIMIT 1

此外,请查看解释以查看导致查询花费如此长时间的部分并确认正在使用索引。

于 2013-08-14T15:05:05.253 回答
0

如果我没有错过任何内容,您的查询应该如下所示:

select t1.*
from asterisk as t1
where
    t1.operator_dial = '203' and
    t1.event = 'Dial' and
    exists (
        select *
        from asterisk as t2
        where
            t2.id <> t1.id and t2.unique_id = t1.unique_id
            t2.event = 'Bridge' and t2.date > t1.date
    ) and
    not exists
    (
        select *
        from asterisk as t3
        where
            t3.id <> t1.id and t3.unique_id = t1.unique_id and
            t3.event = 'Unlink' and t3.date > t1.date
    )
order by t1.date desc
limit 1

但如果你有索引(在 operator_dial 和事件上,以及在日期上),那对性能来说会很棒

于 2013-08-14T15:08:36.343 回答
0
SELECT t1.*
FROM Asterisk t1
INNER JOIN Asterisk t2
  ON t1.unique_id = t2.unique_id
  AND t2.date > t1.date
  AND t2.event = 'Bridge'
LEFT JOIN Asterisk t3
  ON t1.unique_id = t3.unique_id
  AND t3.event = 'Unlink'
WHERE t1.operator_dial = '203'
  AND t1.event = 'Dial'
  AND t3.id IS NULL
ORDER BY t1.date
LIMIT 1

请注意,我省略了 t1.id <> t2.id。事件和日期子句将隐式强制执行此条件。

查看是否有 Dial 事件,然后是 Bridge 事件,但没有 Unlink 事件

我假设“没有取消链接事件”意味着根本没有,尽管您的要求可以理解为“在拨号事件之后没有发生取消链接事件”。如果是后者,您可以将 t3.date > t1.date 添加到联接中以更改功能。

于 2013-08-14T15:18:29.073 回答