我有一个数据库,其中包含一个电信公司的信息,其中包含下表:
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;
但如果其中一个订阅者有多行,
,则此查询将无效例如:
(X1
有L1
行和L2
行
X2
有L3
X3
有L4
)
如果 X1
来自L1
的20个来电,来自L2
的19个来电
X2
来自L3
X3
会话来自L4
我的查询将返回以下输出:
X1
X1
X2
必须返回:
X1
X2
X3
如何修改查询以不返回重复名称?
答案 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