阻止查询返回重复结果

时间:2015-12-31 20:24:45

标签: sql oracle

我有一个数据库,其中包含一个电信公司的信息,其中包含下表:

  • SUBSCRIBERS (SUB_ID , F_NAME , L_NANE , DATE_OF_BIRTH , COUNTRY)

  • LINES (LINE_ID , LINE_NUMBER)

  • SUBSCRIBERS_LINES (SUB_LINE_ID , SUB_ID "foreign key", LINE_ID "foreign key", ACTIVATION_DATE)

  • CALLS (CALL_ID , LINE_FROM "foreign key", LINE_TO "foreign key" , START_DATE_CALL, END_DATE_CALL)

我想检索在特定日期内进行最高计数呼叫次数(每次呼叫持续时间少于60秒)的前3位用户的名称。

所以,我写下面的查询:

with TEMPRESULT AS 
(
    select * from 
    (
      select CALLS.LINE_FROM , count(*) totalcount
      from CALLS
      where (((END_DATE_CALL-START_DATE_DATE)*24*60*60)<=60 and to_char(S_DATE,'YYYY-MM-DD')='2015-12-12') 
      group by CALLS.LINE_FROM
      order by totalcount DESC
    ) 
    where rownum <= 3
) 

select F_NAME,L_NAME
from TEMPRESULT inner join SUBSCRIBERS_LINES on TEMPRESULT.LINE_FROM=SUBSCRIBERS_LINES.line_id inner join SUBSCRIBERS on SUBSCRIBERS_LINES.SUB_ID=SUBSCRIBERS.SUB_ID;

但如果其中一个订阅者有多行,

,则此查询将无效

例如: (X1L1行和L2

X2L3

X3L4

如果 X1来自L1的20个来电,来自L2的19个来电

X2来自L3

的15个电话

X3会话来自L4

的10个电话

我的查询将返回以下输出:

X1

X1

X2

必须返回:

X1

X2

X3

如何修改查询以不返回重复名称?

3 个答案:

答案 0 :(得分:1)

子查询必须在SUB_ID上进行GROUP BY(而不是在LINE_FROM上)。这将提供订阅者的总呼叫而不是顶线呼叫。

换句话说,在子查询和组中移动连接并按SUB_ID排序。

主要查询中的DISTINCT为时已晚,您将不会重复但结果会更少。

答案 1 :(得分:0)

您可以尝试将DISTINCT关键字添加到底部的SELECT查询吗?

这样的事情:

with TEMPRESULT AS 
(
select * from 
(
  select CALLS.LINE_FROM , count(*) totalcount
  from CALLS
  where (((END_DATE_CALL-START_DATE_DATE)*24*60*60)<=60 and to_char(S_DATE,'YYYY-MM-DD')='2015-12-12') 
  group by CALLS.LINE_FROM
  order by totalcount DESC
) 
where rownum <= 3
) 
select DISTINCT F_NAME,L_NAME
from TEMPRESULT
inner join SUBSCRIBERS_LINES on TEMPRESULT.LINE_FROM = SUBSCRIBERS_LINES.line_id
inner join SUBSCRIBERS on SUBSCRIBERS_LINES.SUB_ID = SUBSCRIBERS.SUB_ID;

理论上(我没有通过创建这个数据库来测试它),这应该显示:

X1

X2

X3

答案 2 :(得分:0)

这样的事情怎么样 (T表示查询的结果)

WITH t AS
  (SELECT 1 id, 'x1' subscriber, 'l1' line FROM dual
  UNION ALL
  SELECT 2, 'x1', 'l1' FROM dual
  UNION ALL
  SELECT 3, 'x1', 'l1' FROM dual
  UNION ALL
  SELECT 4, 'x1', 'l2' FROM dual
  UNION ALL
  SELECT 5, 'x1', 'l2' FROM dual
  UNION ALL
  SELECT 6, 'x1', 'l2' FROM dual
  UNION ALL
  SELECT 6, 'x1', 'l2' FROM dual
  UNION ALL
  SELECT 7, 'x2', 'l3' FROM dual
  UNION ALL
  SELECT 8, 'x2', 'l3' FROM dual
  UNION ALL
  SELECT 9, 'x3', 'l4' FROM dual
  ),
  t1 AS
  (SELECT COUNT(subscriber) totalcount,
    line,
    MAX(subscriber) keep (dense_rank last
  ORDER BY line ) subscribers
  FROM t
  GROUP BY line
  ORDER BY 1 DESC
  )
SELECT subscribers,
  listagg(line
  ||' had '
  || totalcount
  || ' calls ', ',') within GROUP (
ORDER BY totalcount) AS lines
FROM t1
GROUP BY subscribers

结果

subscribers       lines
x1                 l1 had 3 calls, l2 had 4 calls
x2                 l3 had 2 calls
x3                 l4 had 1 calls