2013-03-26 9 views
7

Cześć Mam tabeli, który wygląda jakjak znaleźć duplikaty i braki w tym scenariuszu w MySQL

----------------------------------------------------------- 
| id | group_id | source_id | target_id | sortsequence | 
----------------------------------------------------------- 
| 2 | 1  | 2  | 4  |  1  | 
----------------------------------------------------------- 
| 4 | 1  | 20  | 2  |  1  | 
----------------------------------------------------------- 
| 5 | 1  | 2  | 14  |  1  | 
----------------------------------------------------------- 
| 7 | 1  | 2  | 7  |  3  | 
----------------------------------------------------------- 
| 20 | 2  | 20  | 4  |  3  | 
----------------------------------------------------------- 
| 21 | 2  | 20  | 4  |  1  | 
----------------------------------------------------------- 

Scenariusz

Istnieją dwa scenariusze, które muszą być obsługiwane.

  1. Sortsequence wartość kolumna powinna być unikalna na jednym source_id i group_id. Na przykład, jeśli wszystkie rekordy posiadające group_id = 1 AND source_id = 2 powinny mieć unikalny porządek sortowania. W powyższym przykładzie rekordy o id= and 5 which are having group_id = 1 and source_id = 2 have same sortsequence which is 1. To jest wadliwy zapis. Muszę się dowiedzieć tych zapisów.
  2. Jeśli group_id and source_id jest taka sama. sortsequence columns value should be continous. There should be no gap. Na przykład w powyższej tabeli records having id = 20, 21 having same group_id and source_id and sortsequence value is 3 and 1. Nawet to jest wyjątkowe, ale istnieje luka w wartości sortowania. Muszę też dowiedzieć się tych zapisów.

MY So Far Wysiłek

Pisałem zapytanie

SELECT source_id,`group_id`,GROUP_CONCAT(id) AS children 
FROM 
    table 
GROUP BY source_id, 
    sortsequence, 
    `group_id` 
HAVING COUNT(*) > 1 

To zapytanie zająć tylko scenariusz 1. Jak obsługiwać Scenariusz 2? Czy istnieje sposób, aby to zrobić w tym samym zapytaniu lub muszę napisać inny, aby obsłużyć drugi scenariusz.

By the way query will be dealing with million of records in table so performance must be very good.

+0

Czy kolejność sortowania zawsze zaczyna się od 1? Jeśli tak, możesz po prostu uzyskać liczbę i sumę sortowania dla (id_źródła, id_połączenia) i zastosować formułę dla sumy n liczb –

+0

@ChetterHummin Tak, to musi zaczynać się od 1 –

+0

Potem sumowałem wartości i sprawdzałem, czy jest równe count * (count + 1)/2. Może to jednak wymagać zapytania wewnętrznego. Oracle prawdopodobnie miałby pewne funkcje analityczne, aby zrobić to za Ciebie. Ale nie znam odpowiednika w mysql –

Odpowiedz

1

Got odpowiedź od Tere J Komentarze. Poniższe zapytanie obejmuje wyżej wymienione oba kryteria.

SELECT 
    source_id, `group_id`, GROUP_CONCAT(id) AS faultyIDS  
FROM 
    table 
GROUP BY 
    source_id,group_id 
HAVING 
    COUNT(DISTINCT sortsequence) <> COUNT(sortsequence) OR COUNT(sortsequence) <> MAX(sortsequence) OR MIN(sortsequence) <> 1 

Może być może pomóc innym.

0

Spróbuj zapytanie będzie rozwiązać obu przypadkach, jak już wspomniano w pytaniu.

SELECT 
    a.* 
FROM 
    tbl a 
INNER JOIN 
    (select 
     @rn:=IF(@prevG = group_id AND @prevS = source_id, @rn + 1, 1) As rId, 
     @prevG:=group_id AS group_id, 
     @prevS:=source_id AS source_id, 
     id, 
     sortsequence 
    FROM 
     tbl 
    join 
     (select @rn:=0, @prevS:=0, @prevG:=0)b 
    order by group_id, source_id, id) b 
ON a.id = b.id AND a.SORTSEQUENCE <> b.RID; 

FIDDLE

Powiązane problemy