I have a table with 3 Phone columns, I need to run some magic trying to get some records where the phone numbers could match between them, the problem is a Phone number could be on different field between the 2 records.
So I think that a canonical string with the 3 phone numbers should allow me to make the comparison, the problem is the canonizing process. Is there a way to do this? I'm adding a snippet to illustrate what I need to do.
Table is:
╔═════╦══════════╦══════════╦══════════╗
║ ID ║ Phone1 ║ Phone2 ║ Phone3 ║
╠═════╬══════════╬══════════╬══════════╣
║ 123 ║ 555-1234 ║ 666-1235 ║ ║
║ 124 ║ 666-1235 ║ ║ 555-1234 ║
║ 125 ║ 555-8520 ║ 777-7410 ║ 444-9999 ║
╚═════╩══════════╩══════════╩══════════╝
The result I'd be looking for is
╔═════╦══════════════════════════════╗
║ ID ║ ConcatPhones ║
╠═════╬══════════════════════════════╣
║ 123 ║ 555-1234||666-1235 ║
║ 124 ║ 555-1234||666-1235 ║
║ 125 ║ 444-9999||555-8520||777-7410 ║
╚═════╩══════════════════════════════╝
Is there anyway I can do this with a simple variation of CONCAT_WS or a highly efficient stored procedure?
The following should work, if the values are indeed NULL and not blank:
select id,
concat_ws('||', Phone1, Phone2, Phone3)
from t
The reference is here:
CONCAT_WS() does not skip empty strings. However, it does skip any NULL values after the separator argument.
To handle ordering, I would go for:
select id,
group_concat(phone Separator '||' order by phone) as ConcatPhones
from (select t.id,
(case when nums.n = 1 then phone1
when nums.n = 2 then phone2
when nums.n = 3 then phone3
end) as phone
from t cross join
(select 1 as n union all select 2 union all select 3) nums
) p
where phone is not null
group by id
This will filter out any id that doesn't have a phone number.
You can also do this with a giant case statement, although that seems something of a nightmare:
select t.id,
(case when phone1 < phone2 and phone2 < phone3 then concat_ws('||', phone1, phone2, phone3)
when phone1 < phone3 and phone3 < phone2 then concat_ws('||', phone1, phone3, phone2)
. . . through the remaining 4 permuatiations when all three are present
when phone1 is null and phone2 < phone3 then concat_ws('||', phone2, phone3)
. . . through the remaining 5 permutuations when one is NULL
when phone1 is null and phone2 is null then phone3
. . . through the remaining 2 permutations when two are NULL
end) as ConcatPhones
from t
This is more efficient. It is feasible for 3 phone numbers. I wouldn't want to deal with, say, five of them.
来源:https://stackoverflow.com/questions/15773804/order-before-concat-ws