我正在尝试查找personID与不正确的SoundFile(String)相关联的记录。我试图在所有personID中搜索不正确的记录,而不仅仅是一个特定的记录。以下是我的示例表:
TASKS-
PersonID SoundFile(String)
123 D10285.18001231234.mp3
123 D10236.18001231234.mp3
123 D10237.18001231234.mp3
123 D10212.18001231234.mp3
123 D12415.18001231234.mp3
**126 D19542.18001231234.mp3
126 D10235.18001234567.mp3
126 D19955.18001234567.mp3
RECORDINGS-
PhoneNumber(Distinct Records)
18001231234
18001234567
所以在这个例子中,我试图找到所有记录,比如我缩进的记录。大多数声音文件类似于'%18001231234%'与PersonID 123相关联,但是这一条记录是PersonID 126.我需要找到所有记录,其中对于来自Recordings表的所有不同数字,PersonID不是多数。 如果您需要更多信息,请与我们联系! 在此先感谢!!
答案 0 :(得分:1)
; WITH distinctRecordings AS (
SELECT DISTINCT PhoneNumber
FROM Recordings
),
PersonCounts as (
SELECT t.PersonID, dr.PhoneNumber, COUNT(*) AS num
FROM
Tasks t
JOIN distinctRecordings dr
ON t.SoundFile LIKE '%' + dr.PhoneNumber + '%'
GROUP BY t.PersonID, dr.PhoneNumber
)
SELECT t.PersonID, t.SoundFile
FROM PersonCounts pc1
JOIN PersonCounts pc2
ON pc2.PhoneNumber = pc1.PhoneNumber
AND pc2.PersonID <> pc1.PersonID
AND pc2.Num < pc1.Num
JOIN Tasks t
ON t.PersonID = pc2.PersonID
AND t.SoundFile LIKE '%' + pc2.PhoneNumber + '%'
总结一下这一点......第一个CTE distinctRecordings
只是Recordings
中电话号码的一个独特列表。
接下来,PersonCounts
是与每个Tasks
PersonID
中的记录相关联的电话号码计数。
然后将其连接到自身以查找任何重复项,并选择具有较小计数的任何副本...然后将其重新连接回Tasks
以获取该人/电话的违规soundFile
号。
(如果您的架构对其进行了一些小的改进,那么这个查询就会简单得多......)
答案 1 :(得分:0)
在这里,您接收所有对(PersonID
,PhoneNumber
),其中该人使用给定电话号码的条目少于具有最大条目的人。请注意,该查询不适合群组中的多个人。
select agg.pid
, agg.PhoneNumber
from (
select MAX(c) KEEP ( DENSE_RANK FIRST ORDER BY c DESC ) OVER ( PARTITION BY rt.PhoneNumber ) cmax
, rt.PhoneNumber
, rt.PersonID pid
, rt.c
from (
select r.PhoneNumber
, t.PersonID
, count(*) c
from recordings r
inner join tasks t on ( r.PhoneNumber = regexp_replace(t.SoundFile, '^[^.]+\.([^.]+)\.[^.]+$', '\1' ) )
group by r.PhoneNumber
, t.PersonID
) rt
) agg
where agg.c < agg.cmax
;
警告:解决方案是使用oracle语法,但操作应该是当前的sql标准(可能除了regexp_replace
之外,这可能并不重要,因为你的声音文件数据似乎遵循固定位置结构)。