2016-04-22 5 views
6

Hier ist meine Testtabellendaten:Wie kann ich Spalten von Datensätzen aus derselben Tabelle vergleichen?

Testing

ID  Name   Payment_Date Fee    Amt 
1  BankA   2016-04-01  100    20000 
2  BankB   2016-04-02  200    10000 
3  BankA   2016-04-03  100    20000 
4  BankB   2016-04-04  300    20000 

Ich versuche Felder Name, Fee und Amt der einzelnen Datensätze zu vergleichen, um zu sehen, ob die gleichen Werte sind oder nicht. Wenn sie den gleichen Wert haben, möchte ich etwas wie "Y" zu diesen Aufzeichnungen markieren. Hier ist das erwartete Ergebnis

ID  Name   Payment_Date Fee    Amt  SameDataExistYN 
1  BankA   2016-04-01  100    20000 Y 
2  BankB   2016-04-02  200    10000 N 
3  BankA   2016-04-03  100    20000 Y 
4  BankB   2016-04-04  300    20000 N 

Ich habe diese beiden Methoden unten versucht. aber ich suche nach anderen Lösungen, damit ich das Beste für meine Arbeit herausgreifen kann.

Methode 1.

select t.*, iif((select count(*) from testing where name=t.name and fee=t.fee and amt=t.amt)=1,'N','Y') as SameDataExistYN from testing t 

Methode 2.

select t.*, case when ((b.Name = t.Name) 
         and (b.Fee = t.Fee) and (b.Amt = t.Amt)) then 'Y' else 'N' end as SameDataExistYN 
from testing t 
left join (select Name, Fee, Amt 
      from testing 
      Group By Name, Fee, Amt 
      Having count(*)>1 ) as b on b.Name = t.Name 
             and b.Fee = t.Fee 
             and b.Amt = t.Amt 
+0

Versuchen Sie nur, doppelte Datensätze zu finden? – karina

+0

Ja! Ich versuche, doppelte Aufzeichnung zu finden und etw zu markieren –

+0

Ich denke, Ihre erste Methode ist nicht korrekt, da es nur durch den Namen vergleicht. –

Antwort

1

Hier ist eine andere Methode, aber ich glaube, Sie haben Tests auf Ihre Daten laufen, um herauszufinden, was am besten ist:

SELECT 
    t.*, 
    CASE WHEN EXISTS(
    SELECT * FROM testing WHERE id <> t.id AND Name = t.Name AND Fee = t.Fee AND Amt = t.Amt 
) THEN 'Y' ELSE 'N' END SameDataExistYN 
FROM 
    testing t 
; 
+0

Wow! dieser eine arbeitet perfekt und schneller als meine wertvollen Methoden. Danke –

3

Es gibt mehrere Ansätze, mit Unterschieden in der Performance-Eigenschaften.

Eine Option besteht darin, eine korrelierte Unterabfrage auszuführen. Dieser Ansatz ist am besten geeignet, wenn Sie über einen geeigneten Index verfügen und eine relativ kleine Anzahl von Zeilen ziehen.

SELECT t.id 
    , t.name 
    , t.payment_date 
    , t.fee 
    , t.amt 
    , (SELECT 'Y' 
      FROM testing s 
      WHERE s.name = t.name 
      AND s.fee = t.fee 
      AND s.amt = t.amt 
      AND s.id <> t.id 
      LIMIT 1 
     ) AS SameDataExist 
    FROM testing t 
WHERE ... 
LIMIT ... 

Die korrelierte Unterabfrage in der Liste SELECT wird einen Y zurück, wenn es mindestens eine „passende“ Zeile gefunden ist. Wenn keine übereinstimmende Zeile gefunden wird, hat die SameDataExist-Spalte den Wert NULL. Um die NULL in ein 'N' umzuwandeln, könnten Sie die Unterabfrage in eine IFULL() -Funktion einbinden.


Ihre Methode 2 ist ein praktikabler Ansatz. Der Ausdruck in der SELECT-Liste muss nicht all diese Vergleiche durchführen, diese wurden bereits in den Join-Prädikaten gemacht. Alles, was Sie wissen müssen, ist, ob eine übereinstimmende Zeile gefunden wurde ... nur eine der Spalten für NULL/NOT NULL zu testen ist ausreichend.

SELECT t.id 
    , t.name 
    , t.payment_date 
    , t.fee 
    , t.amt 
    , IF(s.name IS NOT NULL,'Y','N') AS SameDataExists 
    FROM testing t 
    LEFT 
    JOIN (-- tuples that occur in more than one row 
     SELECT r.name, r.fee, r.amt 
      FROM testing r 
      GROUP BY r.name, r.fee, r.amt 
     HAVING COUNT(1) > 1 
     ) s 
    ON s.name = t.name 
    AND s.fee = t.fee 
    AND s.amt = t.amt 
WHERE ... 

Sie auch die Verwendung einer VORHANDEN (korrelierte Unterabfrage) machen könnte

+0

Das hilft mir wirklich viel Danke –

1

Select t.name, t.fee, t.amt, wenn (count (*) > 1),‘ Y ',' N ') vom Testen der T-Gruppe nach t.name, t.fee, t.amt