0

私はテーブルを持っています:

契約:

contractid | contract name
"1" | "MAG:001"
"2" | "MAG:002"

- と -

デバイス:

devid | serialnum | fk_contractid
10 | 1234 | 1
11 | 5678 | 1
12 | 4321 | 2
13 | 8765 | 2

devices.fk_contractid = contract.contractid

結果が得られるものを選択する必要があります:

"MAG:001" | 1234, 5678
"MAG:002" | 4321, 8765

PL-SQLでそれをどのように行うことができますか?

4

4 に答える 4

4

11g の場合 (listagg導入時):

  select    CONTRACT_NAME
         || '|'
         || LISTAGG(D.SERIALNUM, ',') within group (order by CONTRACTID)
    from CONTRACTS C join DEVICES D on D.FK_CONTRACTID = C.CONTRACTID
group by CONTRACT_NAME
于 2012-02-20T10:15:45.360 に答える
3

11g ではなく 10g を使用している場合は、LISTAGG に似た隠し機能があります。

WMSYS.WM_CONCAT

SELECT Contracts.contract_name
     , WMSYS.WM_CONCAT(Devices.serialnum)
  FROM Contracts, Devices
 WHERE Contracts.contractid = Devices.fk_contractid
 GROUP BY Contracts.contract_name;

WM_CONCAT ではソートできません。

次のように独自の関数を作成することもできます。

FUNCTION concat_serialnum(the_contract Contracts.contractid%TYPE)
 RETURN VARCHAR2
IS
  return_value VARCHAR2(4000);
  CURSOR serials_cur IS
    SELECT serialnum
      FROM Devices
      WHERE contractid = the_contract
      ORDER BY serialnum;
BEGIN
  FOR serials_rec IN serials_cur LOOP
    return_value := return_value || ', ' || serials_rec.serialnum;
  END LOOP;
  RETURN LTRIM(return_value, ', ');
END concat_serialnum;

4,000 文字の制限を処理するコードを追加する必要があります。

クエリは次のようになります

SELECT contract_name
     , concat_serialnum(contractid)
  from Contracts;
于 2012-02-20T15:39:32.443 に答える
0

次のようにします。

SELECT '"' || c.contract_name || '"'
...
FROM contracts c INNER JOIN devices d ON d.fk_contractid = c.contractid

必要な列を追加します-ダブルバー(思い出すと思います)を使用して文字列を連結します。

引用符を取得する方法を確認するには、実験する必要があります。一重引用符で指定するか、二重引用符で引用符を何らかの方法でエスケープして指定します。

于 2012-02-20T09:52:53.073 に答える
0

11g を使用しておらず、@John Doyle のソリューションを使用できない場合は、独自の集計関数を作成できます。

パフォーマンスの問題を恐れていない場合は、xmlagg を集計関数として使用してから、次のようにフォーマットしてみてください。

select contract_name,
       rtrim(xmlagg(xmlelement(e, serialnum || ',')).extract('//text()')) as serialnums
  from contracts, devices
 where contractId = fk_contractid
 group by contract_name

(チェックしてませんでした)

于 2012-02-20T12:19:34.050 に答える