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
6 Antworten
Sie können die Funktion count()
mit Fenster verwenden.
Abfrage 1 :
SELECT t.*
,CASE
WHEN COUNT(*) OVER (
PARTITION BY fname_lvl1
,lname_lvl1
) > 1
THEN 1
ELSE 0
END AS Flag
FROM t
| 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 |
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
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 |
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
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
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
Verwandte Fragen
Neue Fragen
sql
Structured Query Language (SQL) ist eine Sprache zum Abfragen von Datenbanken. Zu den Fragen sollten Codebeispiele, Tabellenstruktur, Beispieldaten und ein Tag für die verwendete DBMS-Implementierung (z. B. MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 usw.) gehören. Wenn sich Ihre Frage ausschließlich auf ein bestimmtes DBMS bezieht (bestimmte Erweiterungen / Funktionen verwendet), verwenden Sie stattdessen das Tag dieses DBMS. Antworten auf mit SQL gekennzeichnete Fragen sollten ISO / IEC-Standard-SQL verwenden.