对于这种复杂的情况,是否可以在 SQL 中使用递归 CTE 来做到这一点?请建议我任何替代方式
Is it possible to do that using recursive CTE in SQL for this complicated scenario? Please suggest me any alternative way
我的场景:
- 用户A是(骗子)
- 用户B不是(骗子)。但是,系统不允许用户 B
做任何动作。因为 B 和 A 使用相同的 Phone
数字(与欺诈用户共享属性)。(1 层)。
- 用户D不是(骗子)。但是 D 使用与 B 相同的 Deviceid
B 与欺诈用户共享属性。然后也阻止用户 D。在这种情况下,有 2 层。 D与B比较,B与A比较
我的代码:
select ID,
Email,
MobileNo,
DeviceId
from (select * from tableuser
order by ID, Email) tableuser_sorted,
(select @pv := '0122338737', @pc= 'DF1234') initialisation
where find_in_set(MobileNo, @pv)
and length(@pv := concat(@pv, ',', ID))
OR find_in_set(DeviceId, @pc) and length(@pc := concat(@pc,',', ID)
输出:
我在找什么:
- 如果用户是欺诈者。我想将所有属性与其他用户进行比较。
- 如果有任何用户与欺诈用户共享属性,请将该用户的属性与其他用户进行比较。
流程会是这样:
用户A是骗子。好的,与其他用户一起检查用户 A 属性。好的,我发现 B 正在与 A 共享 Phone 号码。B 将在第二阶段。好的,现在检查用户 B 与其他用户的属性。好的,我发现D正在和B共享DeviceId等等。
您可以为此使用递归 CTE。如果你只想要欺诈者,这样的事情应该有效:
with recursive cte as (
select ID, Email, MobileNo, DeviceId, id as ids
from tableuser
where isfraudsterstatus = 1
union all
select u.id, u.email, u.mobileno, u.deviceid, concat_ws(',', cte.ids, u.id)
from cte join
tableuser u
on u.email = cte.email or
u.mobileno = cte.mobileno or
u.deviceid = cte.deviceid
where find_in_set(u.id, cte.ids) = 0
)
select distinct id
from cte;
我的场景:
- 用户A是(骗子)
- 用户B不是(骗子)。但是,系统不允许用户 B 做任何动作。因为 B 和 A 使用相同的 Phone 数字(与欺诈用户共享属性)。(1 层)。
- 用户D不是(骗子)。但是 D 使用与 B 相同的 Deviceid B 与欺诈用户共享属性。然后也阻止用户 D。在这种情况下,有 2 层。 D与B比较,B与A比较
我的代码:
select ID,
Email,
MobileNo,
DeviceId
from (select * from tableuser
order by ID, Email) tableuser_sorted,
(select @pv := '0122338737', @pc= 'DF1234') initialisation
where find_in_set(MobileNo, @pv)
and length(@pv := concat(@pv, ',', ID))
OR find_in_set(DeviceId, @pc) and length(@pc := concat(@pc,',', ID)
输出:
我在找什么:
- 如果用户是欺诈者。我想将所有属性与其他用户进行比较。
- 如果有任何用户与欺诈用户共享属性,请将该用户的属性与其他用户进行比较。
流程会是这样:
用户A是骗子。好的,与其他用户一起检查用户 A 属性。好的,我发现 B 正在与 A 共享 Phone 号码。B 将在第二阶段。好的,现在检查用户 B 与其他用户的属性。好的,我发现D正在和B共享DeviceId等等。
您可以为此使用递归 CTE。如果你只想要欺诈者,这样的事情应该有效:
with recursive cte as (
select ID, Email, MobileNo, DeviceId, id as ids
from tableuser
where isfraudsterstatus = 1
union all
select u.id, u.email, u.mobileno, u.deviceid, concat_ws(',', cte.ids, u.id)
from cte join
tableuser u
on u.email = cte.email or
u.mobileno = cte.mobileno or
u.deviceid = cte.deviceid
where find_in_set(u.id, cte.ids) = 0
)
select distinct id
from cte;