SQL: Как правильно присоединиться, чтобы рассчитать статистику контактов из журнала вызовов - PullRequest
3 голосов
/ 05 июня 2011

Журнал звонков имеет следующие столбцы:

CallingParty, CalledParty, Duration, EventTime

, и пример данных следующий:

X, a, 10, 10:20
X, b, 12, 10:34
X, c, 8, 12:08
a, X, 22, 12:45
X, a, 10, 13:55
d, X, 30, 15:01

То, что я хотел бы сделать, это рассчитать статистику для каждого контакта (сколько раз пользователь X позвонил контакту, какова сумма продолжительности исходящих вызовов, сколько раз контакт позвонил пользователю X, и что была сумма продолжительности входящих звонков). На самом деле я пытаюсь добыть данные из журнала вызовов пользователя X.

Статистика для приведенного выше примера будет следующей:

contactName, incomingCallsCount, IncomingCallsDuration, OutgoingCallsCount, OutgoingCallsDuration
a, 1, 10, 2, 20
b, 0, 0, 1, 12
c, 0, 0, 1, 8
d, 1, 30, 0, 0

Я попробовал следующий запрос с другими joins (), но не смог получить правильный результат

    SELECT t1.CallingParty AS Contact, t1.CallingPartyCount, t1.CallingPartyDuration, t2.CalledPartyCount, t2.CalledPartyDuration FROM
(SELECT e.CallingParty, COUNT(*) AS CallingPartyCount, SUM(CAST(REPLACE(e.Duration, 'NULL', '0') AS int)) AS CallingPartyDuration FROM Events e WHERE Duration <> 'NULL' GROUP BY e.CallingParty) t1
<JOIN>
(SELECT e.CalledParty, COUNT(*) AS CalledPartyCount, SUM(CAST(REPLACE(e.Duration, 'NULL', '0') AS int)) AS CalledPartyDuration FROM Events e WHERE Duration <> 'NULL' GROUP BY e.calledParty) t2
ON t1.CallingParty = t2.CalledParty

Кто-нибудь знает, какой будет правильный запрос для получения правильной статистики?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 05 июня 2011

Попробуйте это:

WITH qry AS
(
    SELECT a.*,
          CASE CallingParty
            WHEN 'X' THEN CalledParty
            ELSE  CallingParty
          END AS contactName
        FROM CallLog a
     WHERE ( CallingParty = 'X' OR  CalledParty = 'X')
)
SELECT  contactName,
        SUM( CASE CallingParty WHEN 'X' 1 ELSE 0 END) AS incomingCallsCount,
        SUM( CASE CallingParty WHEN 'X' Duration ELSE 0 END) AS incomingDurationCount
        SUM( CASE CallingParty WHEN 'X' 0 ELSE 1 END) AS outgoingCallsCount,
        SUM( CASE CallingParty WHEN 'X' 0 ELSE Duration END) AS outgoingDurationCount
  FROM  qry
GROUP BY contactName
2 голосов
/ 05 июня 2011

Вы не должны присоединяться для начала, это больше похоже на простую группу с суммой и количеством.

SELECT CallingParty, CalledParty, SUM(Duration), COUNT(*)
FROM table
GROUP BY CallingParty, CalledParty

Теперь вам также нужен набор всех вовлеченных пользователей (a, b, c и d), который можно вычислить с помощью UNION, если у вас его нет где-то еще.

SELECT CallingParty FROM table
UNION
SELECT CalledParty FROM table

Тогда вы просто соединяете их, используя CTE.

WITH outgoing AS (
    SELECT CallingParty, CalledParty, SUM(Duration), COUNT(*)
    FROM table
    GROUP BY CallingParty, CalledParty
), incoming AS (
    SELECT CalledParty, CallingParty, SUM(Duration), COUNT(*)
    FROM table
    GROUP BY CalledParty, CallingParty
), users AS (
   SELECT CallingParty AS UserID FROM table
   UNION
   SELECT CalledParty AS UserID FROM table
)
SELECT * 
FROM users
LEFT OUTER JOIN outgoing ON outgoing.CallingParty = UserID
LEFT OUTER JOIN incoming ON incoming.CalledParty = UserID

Это должно сделать это!

0 голосов
/ 05 июня 2011

Я бы реализовал это так:

WITH EventsForX AS (
  SELECT
    isIncoming  = CASE CalledParty WHEN @X THEN 1 ELSE 0 END,
    contactName = CASE CalledParty WHEN @X THEN CallingParty ELSE CalledParty END,
    Duration,
  FROM Events
  WHERE CallingParty = @X
     OR CalledParty = @X
)
SELECT
  contactName,
  incomingCallsCount     = SUM(isIncoming),
  incomingCallsDuration  = SUM(isIncoming * Duration),
  outcomingCallsCount    = SUM(1 - isIncoming),
  outcomingCallsDuration = SUM((1 - isIncoming) * Duration)
FROM EventsForX
GROUP BY contactName
0 голосов
/ 05 июня 2011

Это намного проще, чем это:

SELECT contact, 
sum(t1.CallingParty is not null) as CallingPartyCount, 
sum(t1.CallingPartyDuration) as CallingPartyDuration, 
sum(t2.CalledPartyCount is not null) as CalledPartyCount, 
sum(t2.CalledPartyDuration) as CalledPartyDuration
FROM
(select distinct CallingParty as contact from Event) e
left join Event t1 on t1.CallingParty = contact
left join Event t2 on t2.CalledParty = contact
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...