Wie mathguy in den Kommentaren erwähnt, Abfragen wie diese können durch Änderungen an der Konstruktion vereinfacht werden.
Aber angesichts der Daten in diesem Format kann man immer noch einen eindeutigen Satz von TAG
per GROUPID
extrahieren. Hier ist ein Beispiel Ansatz:
In dieser ersten Stufe werden wir REGEXP_COUNT
verwenden, um zu sehen, wie viele TAG
s jede Zeile hat. Dann werden wir erzeugen Positions-Tag-Nummern für jede TAG
in jeder Zeile. Schließlich extrahieren wir das Tag an einer bestimmten Position für jedes Konglomerat TAG
in jeder Zeile.
Erstellen Sie zunächst die Testtabelle:
CREATE TABLE GROUPID_TAG(
GROUPID NUMBER,
"TAG" VARCHAR2(256)
);
INSERT INTO GROUPID_TAG VALUES (1,'Tag1 Tag2');
INSERT INTO GROUPID_TAG VALUES (1,'Tag1 Tag3');
INSERT INTO GROUPID_TAG VALUES (1,'Tag1 Tag4');
INSERT INTO GROUPID_TAG VALUES (2,'Tag5 Tag6');
INSERT INTO GROUPID_TAG VALUES (2,'Tag4 Tag3');
Die folgende Abfrage zwei Spalten, mit einer einzigen TAG
in den ONLY_ONE_TAG
Spalt erzeugen (aber mehr Zeilen pro GROUPID
)
WITH COUNTED_TAG AS (
SELECT GROUPID, "TAG", REGEXP_COUNT("TAG",'(^|)[^ ]{1,}') AS TAG_COUNT FROM GROUPID_TAG),
KEYED_COUNTED_TAG AS (
SELECT GROUPID, "TAG", TAG_COUNT, TAG_KEG_GENERATOR.TAG_KEY FROM COUNTED_TAG
INNER JOIN (SELECT LEVEL AS TAG_KEY FROM DUAL CONNECT BY LEVEL <= 999) TAG_KEG_GENERATOR
ON TAG_KEG_GENERATOR.TAG_KEY <= COUNTED_TAG.TAG_COUNT)
SELECT DISTINCT GROUPID, REPLACE(REGEXP_SUBSTR("TAG",'(^|)[^ ]{1,}',1,TAG_KEY),' ','') AS ONLY_ONE_TAG
FROM KEYED_COUNTED_TAG
ORDER BY 1 ASC, 2 ASC;
es Laufen gibt:
GROUPID ONLY_ONE_TAG
1 Tag1
1 Tag2
1 Tag3
1 Tag4
2 Tag3
2 Tag4
2 Tag5
2 Tag6
Die Daten an dieser Stelle sind möglicherweise einfacher zu bearbeiten als im ursprünglichen Zustand. Aber wenn Sie pro GROUPID in einer Zeile aggregieren möchten, ist hier ein Beispiel dafür. Beginnend mit unserem letzten Abfrage werden wir eine LISTAGG
zu aggregieren Dinge hinzufügen:
WITH COUNTED_TAG AS (
SELECT GROUPID, "TAG", REGEXP_COUNT("TAG",'(^|)[^ ]{1,}') AS TAG_COUNT FROM GROUPID_TAG),
KEYED_COUNTED_TAG AS (
SELECT GROUPID, "TAG", TAG_COUNT, TAG_KEG_GENERATOR.TAG_KEY FROM COUNTED_TAG
INNER JOIN (SELECT LEVEL AS TAG_KEY FROM DUAL CONNECT BY LEVEL <= 999) TAG_KEG_GENERATOR
ON TAG_KEG_GENERATOR.TAG_KEY <= COUNTED_TAG.TAG_COUNT),
DISTINCT_TAG AS(SELECT DISTINCT GROUPID, REPLACE(REGEXP_SUBSTR("TAG",'(^|)[^ ]{1,}',1,TAG_KEY),' ','') AS ONLY_ONE_TAG
FROM KEYED_COUNTED_TAG)
SELECT GROUPID, LISTAGG(ONLY_ONE_TAG,' ') WITHIN GROUP (ORDER BY ONLY_ONE_TAG ASC) AS AGGREGATED_TAG
FROM DISTINCT_TAG
GROUP BY GROUPID
ORDER BY 1 ASC;
Ergebnis:
GROUPID AGGREGATED_TAG
1 Tag1 Tag2 Tag3 Tag4
2 Tag3 Tag4 Tag5 Tag6
Dann fügen Sie einige zusätzliche Tags, für die Prüfung:
INSERT INTO GROUPID_TAG VALUES (1,'Wookie Hobbit @[email protected]');
INSERT INTO GROUPID_TAG VALUES (2,'HAL-9000 Thor');
Und Abfrage erneut:
WITH COUNTED_TAG AS (
SELECT GROUPID, "TAG", REGEXP_COUNT("TAG",'(^|)[^ ]{1,}') AS TAG_COUNT FROM GROUPID_TAG),
KEYED_COUNTED_TAG AS (
SELECT GROUPID, "TAG", TAG_COUNT, TAG_KEG_GENERATOR.TAG_KEY FROM COUNTED_TAG
INNER JOIN (SELECT LEVEL AS TAG_KEY FROM DUAL CONNECT BY LEVEL <= 999) TAG_KEG_GENERATOR
ON TAG_KEG_GENERATOR.TAG_KEY <= COUNTED_TAG.TAG_COUNT),
DISTINCT_TAG AS(SELECT DISTINCT GROUPID, REPLACE(REGEXP_SUBSTR("TAG",'(^|)[^ ]{1,}',1,TAG_KEY),' ','') AS ONLY_ONE_TAG
FROM KEYED_COUNTED_TAG)
SELECT GROUPID, LISTAGG(ONLY_ONE_TAG,' ') WITHIN GROUP (ORDER BY ONLY_ONE_TAG ASC) AS AGGREGATED_TAG
FROM DISTINCT_TAG
GROUP BY GROUPID
ORDER BY 1 ASC;
Ergebnis:
GROUPID AGGREGATED_TAG
1 @[email protected] Hobbit Tag1 Tag2 Tag3 Tag4 Wookie
2 HAL-9000 Tag3 Tag4 Tag5 Tag6 Thor
Schlechte Idee rundherum. Was bedeutet "Ich habe" - ist die Eingabedaten (Ihre erste Tabelle) eine gespeicherte Tabelle, auf der Festplatte? Was bedeutet "Ergebnis" - was wird für die Berichterstattung angezeigt? Wenn dies der Fall ist, ist der Bericht in diesem Format möglicherweise in Ordnung, aber die Basisdaten verletzen eines der grundlegendsten Prinzipien des Designs relationaler Tabellen. So grundlegend, dass es "Erste Normalform" genannt wird. Die beste Lösung in all diesen Fällen ist, Ihre Daten zu normalisieren - wenn Sie nicht in der Datenbank, dann zumindest in Ihrer Abfrage. – mathguy
Jack haben Ihre Daten immer zwei Tags pro GroupId pro Zeile oder eine beliebige Anzahl von Tags pro Zeile? – alexgibbs
wäre es irgendwelche Tags pro Zeile. Und es könnte auch leer sein. Vielen Dank. -Jack – user3595231