Ich bin relativ neu in der Verwendung von SQL. Daher möchte ich Ihre Hilfe in Bezug auf einen Fall.

Ich habe die folgende Tabelle (nur ein Beispiel):

| id | FName_LVL1  | LName_LVL1 | FName_LVL2 | LName_LVL2  |
|----|-------------|------------|------------|-------------|
| 1  | John        | Kennedy    | Marc       | Guy         |
| 2  | John        | Kennedy    | Olivier    | Oslo        |
| 3  | Mike        | Lanes      | Patrick    | James       |

Ich möchte die Duplikate in FName_LVL1 und LName_LVL1 isolieren

Damit die Tabelle so aussieht:

| id | FName_LVL1  | LName_LVL1 | FName_LVL2 | LName_LVL2  |
|----|-------------|------------|------------|-------------|
| 1  | John        | Kennedy    | Marc       | Guy         |
| 2  | John        | Kennedy    | Olivier    | Oslo        |

Meine Idee war es, eine Flag-Spalte mit der Bedingung zu erstellen, dass die IF-Zeilen oben oder unten in Spalte FName_LVL1 und LName_LVL1 identisch sind, und dann "1", sonst "0" zu setzen.

Eine Spalte haben, die so aussieht:

| id | FName_LVL1  | LName_LVL1 | FName_LVL2 | LName_LVL2  | Flag
|----|-------------|------------|------------|-------------|
| 1  | John        | Kennedy    | Marc       | Guy         | 1
| 2  | John        | Kennedy    | Olivier    | Oslo        | 1
| 3  | Mike        | Lanes      | Patrick    | James       | 0

Nachdem ich eine Tabelle wie diese hatte, konnte ich einfach filtern und das Ergebnis erzielen, das ich erreichen möchte.

Das ist eine Arbeitsweise, die ich in Alteryx gewohnt bin, aber ich bin mir nicht sicher, ob dies mit SQL-Anweisungen möglich ist oder ob dies der beste Weg ist, um diesen Fall anzugehen

1
Solide 18 Apr. 2018 im 20:48

6 Antworten

Beste Antwort

Sie können die Funktion count() mit Fenster verwenden.

SQL-Geige

Abfrage 1 :

SELECT t.*
    ,CASE 
        WHEN COUNT(*) OVER (
                PARTITION BY fname_lvl1
                ,lname_lvl1
                ) > 1
            THEN 1
        ELSE 0
        END AS Flag
FROM t

Ergebnisse :

| ID | FNAME_LVL1 | LNAME_LVL1 | FNAME_LVL2 | LNAME_LVL2 | FLAG |
|----|------------|------------|------------|------------|------|
|  1 |       John |    Kennedy |       Marc |        Guy |    1 |
|  2 |       John |    Kennedy |    Olivier |       Oslo |    1 |
|  3 |       Mike |      Lanes |    Patrick |      James |    0 |
2
Yogesh Sharma 19 Apr. 2018 im 06:51

Das no_of_records ist eine Spalte, die angibt, wie oft die Kombination in der Tabelle vorhanden ist. Das heißt, In Ihrer Beispieltabelle ist es 2

select table1.*
from table as table1
inner join
(
  Select FName_LVL1, LName_LVL1, count(*) as no_of_records
  from Table
  group by FName_LVL1, LName_LVL1
) table2
  on table1.FName_LVL1 = table2.FName_LVL1
     and table1.LName_LVL1 = table2.LName_LVL1
     and no_of_records>1
0
Raunak Thomas 18 Apr. 2018 im 17:58

Sie können die Unterabfrage "semi join" verwenden, um ein Ergebnis wie das folgende zu erhalten:

SELECT * FROM Table1 t1
WHERE EXISTS (
  SELECT 'Anything' FROM Table1 t2
  WHERE t1.FName_LVL1 = t2.FName_LVL1
    AND t1.LName_LVL1 = t2.LName_LVL1
    AND t1.id <> t2.id
)

Demo: http://sqlfiddle.com/#!4/f9c44/3

| ID | FNAME_LVL1 | LNAME_LVL1 | FNAME_LVL2 | LNAME_LVL2 |
|----|------------|------------|------------|------------|
|  2 |       John |    Kennedy |    Olivier |       Oslo |
|  1 |       John |    Kennedy |       Marc |        Guy |
0
krokodilko 18 Apr. 2018 im 18:01

Am effizientesten ist es, die Partition by-Klausel zu verwenden, um nur einen Tabellenscan durchzuführen. Ich habe die Ausgabe in Livesql gespeichert

drop table t1 purge;
      create table t1 ( c1 varchar2(20), c2 varchar2(20), c3 varchar2(20), c4 varchar2(20));
      insert into t1 values ('John','Kennedy','Marc','Guy');
      insert into t1 values ('John','Kennedy','Olivier','Oslo');
      insert into t1 values ('not','john','vijay','balebail');
      commit;
      select t1.*, count(c1||c2) over (partition by c1,c2 order by c1,c2  ) flag from t1;
      select t1.*, decode (count(c1||c2) over (partition by c1,c2 order by c1,c2  ),1,0,1) flag from t1;

C1 C2 C3 C4 FLAGGE John Kennedy Marc Guy 2 John Kennedy Olivier Oslo 2 nicht John Vijay Balebail 1 Download CSV 3 Zeilen ausgewählt. Anweisung 7 wähle t1. *, Dekodiere (zähle (c1 || c2) über (Partition nach c1, c2 Reihenfolge nach c1, c2), 1,0,1) Flag von t1

C1      C2      C3      C4       FLAG
John    Kennedy Marc    Guy         1
John    Kennedy Olivier Oslo        1
not     john    vijay   balebail    0
0
Vijay Balebail 18 Apr. 2018 im 18:33

Möglicherweise bevorzugen Sie die Verwendung der Analysefunktionen LAG und LEAD mit dem Beitrag von NVL2:

select n.*,
       nvl2(lag(FName_LVL1||' '||LName_LVL1,1,null) over 
       (partition by FName_LVL1||' '||LName_LVL1 order by FName_LVL1, LName_LVL1),1,0)+
       nvl2(lead(FName_LVL1||' '||LName_LVL1,1,null) over 
       (partition by FName_LVL1||' '||LName_LVL1 order by FName_LVL1, LName_LVL1),1,0) flag
  from names n;

ID FNAME_LVL1   LNAME_LVL1  FNAME_LVL2  LNAME_LVL2  FLAG
--  ----------  ----------  ----------  ----------  -----
1    John        Kennedy      Marc        Guy         1
2    John        Kennedy      Olivier     Oslo        1
3    Mike        Lanes        Patrick     James       0

SQL Fiddle Demo

0
Barbaros Özhan 18 Apr. 2018 im 18:53

Na danke euch allen! Es scheint tatsächlich viele Lösungen für diesen Fall zu geben!

Ich werde mich weiter damit beschäftigen, um zu sehen, was mir am besten gefällt, aber dank Ihnen gibt es mir einen guten Einblick in die SQL-Logik

Entschuldigung für die Verzögerung in meiner Antwort, war wegen der Arbeit weg

0
Solide 20 Apr. 2018 im 11:00