2

いくつかのコンテキスト: DB は Oracle です。テーブルの行ごとに 1 つの区切り文字列を作成しようとしています。区切られた文字列には、アイテムのカテゴリが 2 つ含まれている必要があります (可能な場合は、少なくとも 1 つのカテゴリが常に存在します)。ITEM、ITEM_CAT、ITEM_ITEM_CAT の 3 つのテーブルがあります。ITEM テーブルには、すべてのアイテムが保持されます。ITEM_CAT テーブルには、考えられるすべてのアイテム カテゴリが保持されます。ITEM_ITEM_CAT は、アイテム ID とカテゴリ ID の間のすべてのマッピング、本質的にはキー値テーブルを保持します。

特定のアイテムの区切り文字列を取得できる以下の SQL を作成しましたが、テーブル全体に対して実行できるクエリが必要です。

SELECT 'ITEM'||'%#'|| outerTable.ITEM_ID ||'%#'|| 
    (SELECT midTable.item_cat_nam
     FROM
            (SELECT innerTable.item_cat_nam AS item_cat_nam, innerTable.item_id AS item_id, ROWNUM AS rn
             FROM
                    (SELECT ic.ITEM_CAT_NAM AS item_cat_nam, i.ITEM_ID AS item_id
                     FROM ITEM_CAT ic, ITEM_ITEM_CAT iic, ITEM i
                     WHERE i.ITEM_ID = iic.ITEM_ID 
                     AND iic.ITEM_CAT_CD = ic.ITEM_CAT_CD
                     AND 287484 = i.item_id
                    ) innerTable
            ) midTable
    WHERE rn = 1
    ) ||'%#'||
    (SELECT midTable.item_cat_nam
     FROM
            (SELECT innerTable.item_cat_nam AS item_cat_nam, innerTable.item_id AS item_id, ROWNUM AS rn
             FROM
                    (SELECT ic.ITEM_CAT_NAM AS item_cat_nam, i.ITEM_ID AS item_id
                     FROM ITEM_CAT ic, ITEM_ITEM_CAT iic, ITEM i
                     WHERE i.ITEM_ID = iic.ITEM_ID 
                     AND iic.ITEM_CAT_CD = ic.ITEM_CAT_CD
                     AND 287484 = i.item_id
                    ) innerTable
            ) midTable
    WHERE rn = 2
    )
FROM OFR outerTable
WHERE outerTable.ITEM_ID = 287484;

外部テーブルの ITEM_ID を最後の内部結合に渡すことができる必要があります。カテゴリのみが必要な場合にこれを行うことができます (以下の SQL ステートメントを介して、必要な内部結合は 1 つだけです) が、複数のカテゴリを導入する必要があります。(複数のカテゴリを取得するために) rownum が必要です。これにはさらに内部結合が必要であり、ITEM_ID を複数の内部結合に渡すことができないようです。ここに問題があります...

SELECT 'ITEM'||'%#'|| outerTable.OFR_ID ||'%#'|| 
    (SELECT ic.ITEM_CAT_NAM
     FROM ITEM_CAT ic, ITEM_ITEM_CAT iic, ITEM i
     WHERE i.ITEM_ID = iic.ITEM_ID 
     AND iic.ITEM_CAT_CD = ic.ITEM_CAT_CD
     AND outerTable.OFR_ID = i.item_id
             AND rownum = 1
    ) innerTable
FROM OFR outerTable;

誰でもこれを手伝ってもらえますか?

よろしくお願いいたします。

4

1 に答える 1

2

心配ない。このようなものが必要です...

SELECT 'ITEM' || '%#' || Item_ID || '%#' || CatName1 || '%#' || CatName2
FROM outerTable
INNER JOIN (
  SELECT
    Item_ID,
    MAX(CASE WHEN rn = 1 THEN Item_Cat_Nam ELSE NULL END) CatName1,
    MAX(CASE WHEN rn = 2 THEN Item_Cat_Nam ELSE NULL END) CatName2
  FROM (
    SELECT
      Item_ID,
      Item_Cat.Item_Cat_Nam,
      ROW_NUMBER() OVER (PARTITION BY Item_ID ORDER BY Item_ID) rn
    FROM Item
    INNER JOIN Item_Item_Cat USING (Item_ID)
    INNER JOIN Item_Cat USING (Item_Cat_Cd)
  ) GROUP BY Item_ID
) USING (Item_ID)

最も内側のクエリは、ROW_NUMBER 関数を使用して、各項目で見つかったすべてのカテゴリに 1、2、3 などを割り当てます。PARTITION BY は、各項目の番号付けを 1 から再開します。ORDER BY が必要なので、Item_ID を使用しました。それを使用して順序付けする優先列がある場合は、行番号を割り当てるために使用されます。内部クエリは次のように出力します。

Item_ID  Item_Cat_Nam  rn
-------  ------------  --
      1  Category aa    1
      1  Category xy    2
      1  Category ef    3
      2  Category xy    1
      2  Category ax    2
      3  Category ef    1

最も内側のクエリを囲むクエリは、MAX を使用してrn、各 Item_ID の最初の 2 つの値を 1 つの行にフラット化します。rn=1 の Item_Cat_Nam は CatName1 列に移動し、rn=2 の Item_Cat_Nam は CatName2 列に移動します。上記の結果が供給されると、次のようになります。

Item_ID  CatName1     CatName2
-------  -----------  -----------
      1  Category aa  Category xy  (note Category ef is rn=3 so it's ignored)
      2  Category xy  Category ax
      3  Category ef               (note only one row for Item_ID 3)

次に、非常に外側のクエリがすべてを連結します。

もう 1 つ: 「JOIN ... USING」構文を使用したのは、この場合、すべてのエイリアス (innerTable、i、ic、iic、midTable など) を削除できるためです。それは純粋に、私がそれをより快適に使用できるようになったためです。独自の結合スタイルを自由に使用する必要があります-結局のところ、それを維持するのはあなたです:)

于 2013-03-01T21:39:03.540 に答える