Я могу подумать о двух методах: одном статическом и одном рекурсивном:
Предположим, что в вашей таблице сообщений есть три столбца: message_id, sequence, message_line, где message_id уникально идентифицирует сообщение о дыре, и последовательность перечисляет сообщениеlines.
Если вас интересуют n первых строк, вы можете использовать статический запрос, например
SELECT
A.MESSAGE_ID, A.MESSAGE_LINE || ' ' ||
COALESCE(B.MESSAGE_LINE, '') || ' ' ||
COALESCE(C.MESSAGE_LINE, '') || ' ' ||
COALESCE(D.MESSAGE_LINE, '')
FROM
MESSAGES A
LEFT JOIN MESSAGES B ON A.MESSAGE_ID = B.MESSAGE_ID AND A.SEQUENCE+1 = B.SEQUENCE
LEFT JOIN MESSAGES C ON B.MESSAGE_ID = C.MESSAGE_ID AND B.SEQUENCE+1 = C.SEQUENCE
LEFT JOIN MESSAGES D ON C.MESSAGE_ID = D.MESSAGE_ID AND C.SEQUENCE+1 = D.SEQUENCE
WHERE A.SEQUENCE = 1;
. Если вам нужны все строки, вы можете использовать более сложный рекурсивный запрос, такой какas:
WITH AA (MESSAGE_ID, SEQUENCE, MESSAGE_LINE) AS (
SELECT
MESSAGE_ID,
SEQUENCE,
CAST(MESSAGE_LINE AS VARCHAR(1000))
FROM
MESSAGES
WHERE
SEQUENCE = 1
UNION ALL
SELECT
B.MESSAGE_ID,
B.SEQUENCE,
CAST((AA.MESSAGE_LINE || ' ' || B.MESSAGE_LINE) AS VARCHAR(1000))
FROM
MESSAGES B,
AA
WHERE
B.MESSAGE_ID = AA.MESSAGE_ID
AND B.SEQUENCE = AA.SEQUENCE + 1
)
SELECT AA.MESSAGE_ID, AA.MESSAGE_LINE
FROM AA, (SELECT MESSAGE_ID, MAX(SEQUENCE) AS SEQUENCE
FROM MESSAGES
GROUP BY MESSAGE_ID) BB
WHERE AA.MESSAGE_ID = BB.MESSAGE_ID
AND AA.SEQUENCE = BB.SEQUENCE;
Советы:
(1) первый запрос перед UNION ALL является нерекурсивной частью, искрой, которая зажигает запрос.Часть после UNION ALL является рекурсивной.
(2) CAST (...) должен преобразовать CHAR (80) в больший столбец, достаточно большой для размещения сообщения о дыре.
Будьте осторожны с производительностью.Настройка рекурсивных запросов может быть сложной, а в некоторых случаях будет проще разработать обычную хранимую процедуру или пользовательскую табличную функцию (UDTF).