2016-12-07 1 views
2

Wie kann ich den Inhalt einer großen Tabelle (1 m bis 5 m) effizient mischen? Es ist bekannt, dass die Spalte eindeutige Werte hat, aber Sie können davon ausgehen, dass alle Einschränkungen für diese Zwecke entfernt werden. Meine Kopfschmerzen sind hauptsächlich, weil ich die selbe Spalte aktualisiere, die ich auswähle. Mein Ziel ist es, dies mit PL/SQL zu tun, so dass ich programmatisch zusätzliche Aktionen wie die Protokollierung oder Aktualisierung anderer Tabellen ausführen kann.Eine Spalte zwischen Zeilen mischen

**Original table:** 
+----+-----------+ 
| id | fname  | 
+----+-----------+ 
| 1 | mike  | 
| 2 | ricky  | 
| 3 | jane  | 
| 4 | august | 
| 6 | dave  | 
| 9 | Jérôme | 
+----+-----------+ 

**Possible output:** 
+----+-----------+ 
| id | fname  | 
+----+-----------+ 
| 1 | dave  | 
| 2 | jane  | 
| 3 | mike  | 
| 4 | ricky  | 
| 6 | Jérôme | 
| 9 | august | 
+----+-----------+ 

Meine letzten Versuche haben einen Cursor zu erstellen, die over (order by dbms_random.value) verwendet und versuchen, eine Zusammenführung zu tun oder vielleicht basierend auf rownum aktualisieren. Vielleicht kann ich die modifizierende Selbstbeschränkung umgehen, indem ich eine temporäre Tabelle von Arten erstelle? Ich bin mir ziemlich sicher, dass Oracle eine raffinierte Möglichkeit hat, dies zu tun, aber ich bin in meinen SQL-Fähigkeiten auf die grundlegenden CRUD-Befehle beschränkt.

Die vollständige Lösung ist hier, basierend auf Gordon Antwort:

merge into t 
using (
select t.id, t2.name 
from (select t.*, rownum as seqnum 
     from t 
    ) t join 
    (select t.*, row_number() over (order by dbms_random.value) as seqnum 
     from t 
    ) t2 
    on t.seqnum = t2.seqnum 
) src 
on (t.id = src.id) 
when matched then update set t.name = src.name; 

Antwort

2

Sie einen Self-Join tun können, zufällige Zeilennummern mit:

select t.id, t2.name 
from (select t.*, row_number() over (order by dbms_random.value) as seqnum 
     from t 
    ) t join 
    (select t.*, row_number() over (order by dbms_random.value) as seqnum 
     from t 
    ) t2 
    on t.seqnum = t2.seqnum; 

Eigentlich brauchen Sie nicht für beide zu randomisiert werden:

+0

Danke für die Antwort, man Haarspalterei ich habe, ist, dass die t1 gerade sein sollte t . Wie auch immer, wie würde ich ein Update davon bekommen? Müsste ich eine Zusammenführungsanweisung basierend auf dieser Abfrage generieren? – user1

+0

Ich konnte es mit Merge arbeiten, danke nochmal. Ich werde die vollständige Lösung in meiner Frage veröffentlichen. – user1

1

Direkt von dieser Antwort (es war meins, so glaube ich, ich bin erlaubt zu reus e it): https://community.oracle.com/thread/3995265

Vorbereitung

create table original_table (id number, name varchar2(30)); 

insert into original_table 
    select 1, 'mike' from dual union all 
    select 2, 'ricky' from dual union all 
    select 3, 'jane' from dual union all 
    select 4, 'august' from dual union all 
    select 6, 'dave' from dual union all 
    select 9, 'Jérôme' from dual 
; 

select * from original_table; 

ID NAME 
-- ------ 
1 mike 
2 ricky 
3 jane 
4 august 
6 dave 
9 Jérôme 

Aktualisierung der Zeilen mit vertauschten Namen:

merge into original_table o 
    using (
    with 
     helper (id, rn, rand_rn) as (
      select id, 
        row_number() over (order by id), 
        row_number() over (order by dbms_random.value()) 
      from original_table 
     ) 
    select ot.name, h2.id 
    from original_table ot inner join helper h1 on  ot.id = h1.id 
          inner join helper h2 on h1.rand_rn = h2.rn 
) p 
on (o.id = p.id) 
when matched then update set o.name = p.name 
; 

select * from original_table; 

ID NAME 
-- ------ 
1 ricky 
2 dave 
3 Jérôme 
4 jane 
6 august 
9 mike 
+0

Dies ist eine großartige Lösung. Ich habe das gleiche Problem, aber ich muss das Geschlecht jedes Namens garantieren: männlich, weiblich und unbekannt. Wie kann ich diese Bedingung auf diese Lösungen anwenden? Irgendwelche Gedanken? – milheiros

+0

@milheiros - Haben Sie eine separate Spalte für Geschlecht, oder müssen Sie es von dem Namen erraten? – mathguy

Verwandte Themen