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;