Используйте результаты SQL, чтобы сделать новый запрос - PullRequest
1 голос
/ 18 марта 2011

Вопрос связан с информацией о телефонии, хотя я использую Genesys http://www.genesyslab.com,, но я предпочел разместить здесь вопрос, потому что это вопрос, связанный с SQL. У меня есть две таблицы:

(Таблица 1: " CallerID ") Одна таблица, содержащая CallerID и ConnID (идентифицирует вызов). (Таблица 2: " Callinfo ") Другая таблица содержит, помимо прочего, CallerID, дату входящего вызова (хранится в формате int с возможностью его перевода ) и строка состояния, которая соответствует действию, которое я объясню ниже. Один пример строки

ConnID                StartTime   Status
--------------------- ----------- -----------
30119914212527698     1300286888  2

Каждый раз, когда поступает вызов, обе таблицы обновляются. Что мне нужно сделать, это получить все звонки, которые поступили в последние два дня со статусом 2 или 4 (это звонки, на которые не был дан ответ) из Callinfo и получить CallerID из таблицы CallerID. После этого мне нужно проверить, есть ли у того же CallerID новые регистры в таблице Callinfo, проверяя его ConnID. Если эти новые регистры имеют статус, отличный от 2 o 4 (означает успех в обмене данными), я должен удалить CallerID первого запроса.

Цель запроса - вызвать тех клиентов, которые пытались позвонить в течение последних двух дней, но не смогли.

Первый запрос работает нормально, вы должны игнорировать функцию DATEDIFF.

DECLARE @twoDays BIGINT
SET @twoDays = 172800   --48hs expressed in seconds

SELECT DISTINCT ConnID, StartTime, CID.CallerID, Status FROM Callinfo
INNER JOIN dbo.CallerID CID
    ON Callinfo.ConnID = CID.ConnID
WHERE 
    (Status = 2 OR Status = 4)
    AND 
    StartTime > DATEDIFF(second, '1970-01-01 00:01:00', GETUTCDATE())- @twoDays

Я не знаю, как использовать результаты и проверять, есть ли новые звонки со статусом, отличным от 2 и 4.

Я работаю на SQL Server 2005.

Следующая последовательность может проясниться: Если с вызывающим абонентом A такая ситуация:

1/1 12pm: A call OK 
1/1 1pm: A call FAIL 

тогда я должен получить результат. Но если ситуация такова:

1/1 12pm: A call OK 
1/1 1pm: A call FAIL 
2/1 12pm: A call OK 

тогда я не должен получить A в результате. Таким образом, когда я проверяю 3/1, я не получу результат, потому что последний вызов от A был в порядке, а 4/1 вызывающий абонент A не должен появляться в первом запросе.

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

Примерно так должно быть быстрее.

DECLARE @twoDaysAgo DateTime
SET @twoDaysAgo = DATEADD(day,-2,GETDATE())

WITH MissedCalls AS
(
  SELECT DISTINCT ConnID, StartTime, CID.CallerID, Status FROM Callinfo
  JOIN dbo.CallerID CID ON Callinfo.ConnID = CID.ConnID
  WHERE Status IN (2,4)
    AND StartTime > @twoDaysAgo
), NotMissedCalls AS
(
   SELECT DISTINCT ConnID, StartTime, CID.CallerID, Status 
   FROM Callinfo
   JOIN dbo.CallerID CID ON Callinfo.ConnID = CID.ConnID
   WHERE Status not in (2,4)
    AND StartTime > @twoDaysAgo
    -- following line may speed up or slow down depending on table sizes and indexes
    AND CID.CallerID in (SELECT CALLERID FROM MissedCalls)
)
SELECT *
FROM MissedCalls
WHERE NOT CallerID IN (SELECT CallerID FROM NotMissedCalls)

ПРИМЕЧАНИЕ: я не проверял, поэтому у меня могут быть опечатки. На всякий случай я поставил все столбцы для всех запросов, но я ожидаю, что это можно улучшить. (Меньше столбцов должно быть немного быстрее.)


Это решает новую проблему.

DECLARE @twoDaysAgo DateTime
SET @twoDaysAgo = DATEADD(day,-2,GETDATE())

WITH MissedCalls AS
(
  SELECT ConnID, Max(StartTime) as LastFailDate, CID.CallerID  FROM Callinfo
  JOIN dbo.CallerID CID ON Callinfo.ConnID = CID.ConnID
  WHERE Status IN (2,4)
    AND StartTime > @twoDaysAgo
  GROUP BY ConnID, CID.CallerID
), NotMissedCalls AS
(
   SELECT ConnID,Max(StartTime) as LastGoodDate,CID.CallerID 
   FROM Callinfo
   JOIN dbo.CallerID CID ON Callinfo.ConnID = CID.ConnID
   WHERE Status not in (2,4)
    AND StartTime > @twoDaysAgo
    -- following line may speed up or slow down depending on table sizes and indexes
    AND CID.CallerID in (SELECT CALLERID FROM MissedCalls)
   GROUP BY ConnID, CID.CallerID
), CallList AS
(
   SELECT LastFailDate, LastGoodDate, Bad.ConnID, Bad.CallerID
   FROM MissedCalls Bad
   JOIN NotMissedCalls Good ON Bad.ConnID = Good.ConnID AND Bad.CallerID = Good.CallerID
)
SELECT LastFailDate, ConnID, CallerID
FROM CallList
WHERE (LastGoodDate > LastFailDate) OR (LastGoodDate IS NULL)
1 голос
/ 18 марта 2011

Мне кажется, у меня есть рабочая база.

DECLARE @twoDays BIGINT
SET @twoDays = 172800   --48hs expressed in seconds

SELECT DISTINCT ConnID, StartTime, CID.CallerID, Status FROM Callinfo
INNER JOIN dbo.CallerID CID
    ON Callinfo.ConnID = CID.ConnID
WHERE 
    (Status = 2 OR Status = 4)
    AND 
    StartTime > DATEDIFF(second, '1970-01-01 00:01:00', GETUTCDATE())- @twoDays
    AND CID.CallerID NOT IN (
        SELECT DISTINCT CID.CallerID FROM Callinfo
        INNER JOIN dbo.CallerID CID
        ON Callinfo.ConnID = CID.ConnID
        WHERE 
            (Status <> 2 AND Status <> 4)    
        AND 
            StartTime > DATEDIFF(second, '1970-01-01 00:01:00', GETUTCDATE())- @twoDays
        )

Этот запрос удаляет идентификатор вызывающего абонента, когда он появляется во втором запросе, то есть вызывающему абоненту, которому удается позвонить в течение последних 2 дней.

Недостаток: он не может определить, если A вызывает день 1, вспоминает день 2 и терпит неудачу (диапазон от дня 1 до дня 3). Но он сделает рейз на следующей проверке, когда вы будете пробовать день 2 - день 4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...