;WITH cte AS (
SELECT
*
,ROW_NUMBER() OVER (ORDER BY Column2) AS RowNumber
FROM
@Table
)
SELECT
*
,DENSE_RANK() OVER (ORDER BY A27.Column2) as GroupingId
FROM
cte A27
LEFT JOIN cte A28
ON A28.RowNumber IN (a27.RowNumber + 1, a27.RowNumber + 2)
AND A28.Column1 = 'A28'
WHERE
A27.Column1 = 'A27'
Поскольку основанный на изображении Column3
не является уникальным только номера строк, которые вы хотите, я не пошел по пути его использования. Вместо этого я использовал ROW_NUMBER
на основе Column2
, который выглядит как первичный ключ приращения, а затем просто LEFT SELF JOIN
. Это для 2 строк A28 AFTER
каждой строки A27. если вы хотите «preceding
», как ваш OP говорит, но не предполагает, то просто повернуть его вспять путем изменений JOIN
условия:
ON A28.RowNumber IN (a27.RowNumber - 1, a27.RowNumber - 2)
Примечание Я добавил GroupingID
дать вам способ идентификации, который A27 и A28 являются вместе он может использоваться как новый первичный ключ в вашей таблице A27 и внешний ключ в вашей таблице A28 для сохранения отношений.
Вот данные испытаний, которые я использовал.
DECLARE @Table AS TABLE (Column1 CHAR(3), Column2 BIGINT, Column3 BIGINT)
INSERT INTO @Table VALUES
('A27',346467408,68723601)
,('A28',346467409,68723601)
,('A28',346467411,68723601)
,('A27',346467413,68723601)
,('A28',346467414,68723601)
,('A28',346467416,68723601)
,('A27',349454768,8908697809)
,('A28',349454769,8908697809)
,('A28',349454771,8908697809)
Edit: В соответствии с Вашим комментарием о том, как это сделать, когда в отдельных таблицах. Вы можете использовать объединение всех объединить таблицы:
DECLARE @A27 AS TABLE (Column1 CHAR(3), Column2 BIGINT, Column3 BIGINT)
DECLARE @A28 AS TABLE (Column1 CHAR(3), Column2 BIGINT, Column3 BIGINT)
INSERT INTO @A27 VALUES
('A27',346467408,68723601)
,('A27',346467413,68723601)
,('A27',349454768,8908697809)
INSERT INTO @A28 VALUES
('A28',346467409,68723601)
,('A28',346467411,68723601)
,('A28',346467414,68723601)
,('A28',346467416,68723601)
,('A28',349454769,8908697809)
,('A28',349454771,8908697809)
;WITH cteUnion AS (
SELECT
Column1, Column2, Column3
FROM
@A27
UNION ALL
SELECT
Column1, Column2, Column3
FROM
@A28
)
, cteRowNum AS (
SELECT * ,ROW_NUMBER() OVER (ORDER BY Column2) AS RowNumber
FROM
cteUnion
)
SELECT *, DENSE_RANK() OVER (ORDER BY a27.Column2) as GroupingId
FROM
cteRowNum a27
LEFT JOIN cteRowNum a28
ON a28.RowNumber IN (a27.RowNumber + 1, a27.RowNumber + 2)
AND a28.Column1 = 'A28'
WHERE
a27.Column1 = 'A27'
Если таблицы больше или производительность может быть проблемой, вы можете создать временную таблицу и сделать это таким образом.
IF OBJECT_ID('tempdb..#Combined') IS NOT NULL
BEGIN
DROP TABLE #Combined
END
CREATE TABLE #Combined (
TableName CHAR(3)
,Column2 BIGINT
)
INSERT INTO #Combined (TableName, Column2)
SELECT Column1, Column2
FROM
@A27
INSERT INTO #Combined (TableName, Column2)
SELECT Column1, Column2
FROM
@A28
;WITH cteRowNum AS (
SELECT * ,ROW_NUMBER() OVER (ORDER BY Column2) AS RowNumber
FROM
#Combined
)
SELECT *, DENSE_RANK() OVER (ORDER BY a27.Column2) as GroupingId
FROM
cteRowNum a27
LEFT JOIN cteRowNum a28
ON a28.RowNumber IN (a27.RowNumber + 1, a27.RowNumber + 2)
AND a28.TableName = 'A28'
WHERE
a27.TableName = 'A27'
Бит путается, пожалуйста, сообщите об ожидаемом выходе и укажите названия столбцов. – Susang
Из вашего описания в таблице нет ничего, что связывает родителя (A27) с дочерним элементом (A28), отличным от близости. В Oracle поиск данных не является детерминированным - порядок, в который будут извлекаться данные, изменится, если вы не укажете порядок. У вас нет ключа, который вы можете использовать для заказа, так что это будет проблемой. Возможно, SQL Server отличается. –
Предполагая, что вы * можете * надежно связать родителя с дочерним, тогда вам нужно назначить идентификатор для каждого родителя и указать его на дочернем. Вставьте данные в свои две таблицы, и объединение тривиально. –