、このようなクエリは、設計の変更により簡素化することができます。
ただし、この形式のデータを使用すると、につき、TAG
のユニークなセットを引き出すことができます。ここに例のアプローチがあります:
この最初の段階では、を使用して、各行に含まれるTAG
の数を確認します。次に、は、各行にそれぞれTAG
の位置タグ番号を生成します。最後に、各行の各複合語TAG
の所定の位置にタグを抽出します。
まず、テストテーブルを作成:(GROUPID
あたりが、より多くの行)ONLY_ONE_TAG
列
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;
に以下のクエリは2つの列を生成します
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');
、単一TAG
では、それを実行します与える:
GROUPID ONLY_ONE_TAG
1 Tag1
1 Tag2
1 Tag3
1 Tag4
2 Tag3
2 Tag4
2 Tag5
2 Tag6
この時点でのデータは、元の状態よりも扱いやすい場合があります。しかし、GROUPIDごとに1つの行に再集計したい場合は、その例を示します。私たちの最後のクエリから始めて、私たちは物事を集約するLISTAGG
を追加します:
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;
結果:
GROUPID AGGREGATED_TAG
1 Tag1 Tag2 Tag3 Tag4
2 Tag3 Tag4 Tag5 Tag6
を次に、テストのために、いくつかの追加のタグを追加:
INSERT INTO GROUPID_TAG VALUES (1,'Wookie Hobbit @[email protected]');
INSERT INTO GROUPID_TAG VALUES (2,'HAL-9000 Thor');
をと再度クエリ:
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;
結果:
GROUPID AGGREGATED_TAG
1 @[email protected] Hobbit Tag1 Tag2 Tag3 Tag4 Wookie
2 HAL-9000 Tag3 Tag4 Tag5 Tag6 Thor
悪い考えがすべてです。 「私が持っている」とは何ですか?入力データ(最初のテーブル)はディスク上のストアド・テーブルですか? 「結果」とは何を意味しますか?報告目的のために表示されるものは何ですか?その場合、おそらくその形式でレポートを取得することはOKですが、基本データはリレーショナルテーブル設計の最も基本的な原則の1つに違反します。基本的には、実際には「最初の標準形」と呼ばれています。そのような場合の最善の解決策は、データを正規化することです。データベースにアクセスできない場合は、少なくとも照会することができます。 – mathguy
Jackには、1行あたりGroupIdごとに2つのタグ、または1行に任意の数のタグが常に付いていますか? – alexgibbs
行ごとに任意のタグになります。そしてそれは空にもなる可能性があります。ありがとう。 -Jack – user3595231