按ID查找不正确的记录

时间:2013-08-09 17:05:36

标签: sql sql-server

我正在尝试查找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不是多数。 如果您需要更多信息,请与我们联系!          在此先感谢!!

2 个答案:

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

SQL Fiddle Here

总结一下这一点......第一个CTE distinctRecordings只是Recordings中电话号码的一个独特列表。

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

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

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

答案 1 :(得分:0)

在这里,您接收所有对(PersonIDPhoneNumber),其中该人使用给定电话号码的条目少于具有最大条目的人。请注意,该查询不适合群组中的多个人。

    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之外,这可能并不重要,因为你的声音文件数据似乎遵循固定位置结构)。