Sql 表自连接问题-需要所需的输出
我有一张结构如下的表格:Sql 表自连接问题-需要所需的输出,sql,common-table-expression,recursive-query,Sql,Common Table Expression,Recursive Query,我有一张结构如下的表格: OLD_ID New_ID Month_Number ------ ------ ------------ A 1 A B 2 B C 3 C D 4 我需要一个ID为“A”的表输出,如下所示: New_ID Oldest_Id Latest_ID ------ ---------
OLD_ID New_ID Month_Number
------ ------ ------------
A 1
A B 2
B C 3
C D 4
我需要一个ID为“A”的表输出,如下所示:
New_ID Oldest_Id Latest_ID
------ --------- ---------
A A D
B A D
C A D
D A D
使用月号可以找到最早的\u Id和最新的\u Id
请注意,我是SQL新手。这个答案假设Microsoft SQL Server,但通过对语法的调整,这可以适用于任何DB类型,只要它具有临时表、行计数和用户定义变量,后者只是为了安全起见,以免出现循环。该答案还假设源表是可示例的,[New_ID]列包含所有ID,并且只有当相应的[Month_Number]值合适时,才应考虑较旧/较新的ID,例如,对于较旧的ID,LTE较新ID的[Month_Number] 基本上,我设想的是创建两个临时表:第一个表列出每个[ID]以及[ID]的第一个[Old_ID],第二个表列出最后一个[New_ID]的相同内容: ID1和ID2中的记录设置为首先引用它们自己。然后,对于循环中的每个过程,id的值将在下一步更新(如果可用)。当没有其他事情要做时,迭代停止 以下是每个过程中发生的情况: 通过1: *旧:B->A;C->B;D->C 新增:A->B;B->C;C->D 通过2: 旧:C->A;D->B 新增:A->C;B->D 通过3: 旧:D->A 新:A->D 通过4: 无需采取更多行动 @cutoff变量只是为了防止在ID“A”引用旧ID“B”和ID“B”引用旧ID“A”时永远循环
这不是一个非常有效的方法,通过一些实践,您可能会做得更好:例如,将两个旧动作/新动作结合在一起,但我将把这留给您: 请用您正在使用的数据库标记您的问题。
-- Create temporary tables and declare cutoff variable
DECLARE @cutoff TINYINT;
SET @cutoff = 0;
CREATE TABLE #ID1 (
[ID] CHAR(1) NOT NULL
,[Oldest_ID] CHAR(1) NOT NULL
,[Month_Number] TINYINT NOT NULL
);
CREATE TABLE #ID2 (
[ID] CHAR(1) NOT NULL
,[Latest_ID] CHAR(1) NOT NULL
,[Month_Number] TINYINT NOT NULL
);
-- Initialise temporary tables
INSERT INTO #ID1 ([ID],[Oldest_ID],[Month_Number])
SELECT [New_ID],[New_ID],[Month_Number]
FROM #ExampleTable;
INSERT INTO #ID2 ([ID],[Latest_ID],[Month_Number])
SELECT [ID],[ID],[Month_Number]
FROM #ID1;
-- Fetch oldest IDs first
WHILE(@@ROWCOUNT != 0 AND @cutoff <= 100)
BEGIN
SET @cutoff = @cutoff + 1;
UPDATE oldies
SET oldies.[Oldest_ID] = d.[OLD_ID]
,oldies.[Month_Number] = d.[Month_Number]
FROM #ID1 AS oldies
JOIN #ExampleTable d
ON oldies.[Oldest_ID] = d.[New_ID]
WHERE d.[Month_Number] <= oldies.[Month_Number]
AND d.[OLD_ID] IS NOT NULL;
END;
-- Now the... "newies"
WHILE(@@ROWCOUNT != 0 AND @cutoff <= 100)
BEGIN
SET @cutoff = @cutoff + 1;
UPDATE newies
SET newies.[Latest_ID] = d.[New_ID]
,newies.[Month_Number] = d.[Month_Number]
FROM #ID2 AS newies
JOIN #ExampleTable d
ON newies.[Latest_ID] = d.[OLD_ID]
WHERE d.[Month_Number] >= newies.[Month_Number];
END;
-- Finally, do as you wish with #ID1 and #ID2
SELECT d.[New_ID] AS [ID]
,f1.[Oldest_ID]
,f2.[Latest_ID]
FROM #ExampleTable AS d
JOIN #ID1 AS f1 ON d.[New_ID] = f1.[ID]
JOIN #ID2 AS f2 ON d.[New_ID] = f2.[ID]
;