0

我正在尝试查找 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 不是大多数. 如果您需要更多信息,请与我们联系!提前致谢!!

4

2 回答 2

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 + '%'

SQL小提琴在这里

总结一下这是做什么的...第一个 CTEdistinctRecordings只是 中电话号码的不同列表Recordings

接下来,是与每个PersonCounts中的记录相关联的电话号码计数。TasksPersonID

然后将其连接到自身以查找任何重复项,并选择具有较小计数的任何重复项...然后将其连接回以获取该人/电话号码Tasks的违规行为。soundFile

(如果您的架构对它进行了一些小的改进,那么这个查询会简单得多......)

于 2013-08-09T17:30:16.970 回答
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,这可能无关紧要,因为您的声音文件数据似乎遵循固定位置结构)。

于 2013-08-09T17:49:28.300 回答