In a phone network there are callers: from_number and receivers: to_numbers.
I need a list of all distinct aussi numbers out of the from_number and to_numbers columns/ variables. The list needs to act as a filter and indicate the direction, as in 'from' or 'to'. If the number re-occurred at any location in both fields, that is at any location in the from_number and at any location of the to_numbers field, then this should be indicated as both.
I have an example code: the desired outcome as well what I tried:
create table calls
(
call_date date,
from_number varchar(16),
to_number varchar(16)
);
INSERT calls
VALUES ('2020-07-03','619876544', '022445545'),
( '2020-07-03','61123456', '642445544'),
('2020-07-03','03123456', '61333333'),
('2020-07-03','65123456', '619876543'),
('2020-07-04','642445545', '61123456'),
( '2020-07-04','61333333', '632445555'),
('2020-07-04','642445545', '049876543'),
('2020-07-03','649876543', '61333333'),
( '2020-07-04','612445555', '022445545');
SELECT DISTINCT
callers.*,
FROM calls callers
the desired outcome with the direction : to, from, both:
create table calls
(
call_date date,
from_number varchar(16),
to_number varchar(16),
direction varchar (8)
);
INSERT calls
VALUES ('2020-07-03','619876544', '022445545', 'from'),
( '2020-07-03','61123456', '642445544', 'both'),
('2020-07-03','03123456', '61333333', 'both'),
('2020-07-03','65123456', '619876543', 'to'),
('2020-07-04','642445545', '61123456', 'both'),
( '2020-07-04','61333333', '632445555', 'both'),
('2020-07-04','642445545', '049876543', 'none'),
('2020-07-03','649876543', '61333333', 'both'),
( '2020-07-04','612445555', '022445545', 'from');
SELECT DISTINCT
callers.*
FROM calls callers
How can I see, whether a number re-occurred anywhere in [From_Number] AND [To_Number] and set the direction to both in this case? If it only occurred in a from Number, then it should be set to from, if it occurred only in a to number then should be set to : to
what I tried:
create table calls
(
call_date date,
from_number varchar(16),
to_number varchar(16),
direction varchar (8)
);
INSERT calls
VALUES ('2020-07-03','619876544', '022445545', 'to'),
( '2020-07-03','61123456', '642445544', 'both'),
('2020-07-03','03123456', '61333333', 'both'),
('2020-07-03','65123456', '619876543', 'to'),
('2020-07-04','642445545', '61123456', 'both'),
( '2020-07-04','61333333', '632445555', 'both'),
('2020-07-04','642445545', '049876543', '0'),
('2020-07-03','649876543', '61333333', 'both'),
( '2020-07-04','612445555', '022445545', 'from');
SELECT DISTINCT
callers.call_date
,callers.[From_Number]
,callers.[To_Number]
,DIRECTION = ISNULL(recipients.From_Number, 'both')
--,CASE
--WHEN LEFT (callers.[From_Number] ,2) = '61' then 'from'
--WHEN LEFT (callers.[To_Number] ,2) = '61' then 'to' ELSE '0' END AS direction1
FROM calls callers
LEFT JOIN calls recipients
ON recipients.from_number = callers.to_number;
Lent on a previous question it is likely to be something like this. How can I set the:
,DIRECTION = ISNULL(recipients.From_Number, 'both')
in a way that it does what I need and DIRECTION can be filtered for to / from / both ?
CodePudding user response:
This is a good place to unpivot using apply:
select v.number,
(case when min(v.direction) = max(v.direction)
then min(v.direction)
else 'both'
end),
count(*)
from calls c cross apply
(values (from_number, 'from'),
(to_number, 'to')
) v(number, direction)
group by number;
CodePudding user response:
Given that you say there is only ever one side which starts with 61, and these are the ones you want to count to establish the direction calls have been made, you can calculate which number to use inside an APPLY, then use window functions over that:
SELECT c.*,
CASE WHEN COUNT(CASE WHEN from_number LIKE '61%' THEN 1 END) OVER (PARTITION BY v.num) > 0
THEN
CASE WHEN COUNT(CASE WHEN to_number LIKE '61%' THEN 1 END) OVER (PARTITION BY v.num) > 0
THEN 'both'
ELSE 'from'
END
ELSE
CASE WHEN COUNT(CASE WHEN to_number LIKE '61%' THEN 1 END) OVER (PARTITION BY v.num) > 0
THEN 'to'
ELSE 'none'
END
END
FROM calls c
CROSS APPLY (VALUES
(CASE WHEN from_number LIKE '61%' THEN from_number
WHEN to_number LIKE '61%' THEN to_number
END)
) v(num);
