我有一张下面结构的表格:
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
可以使用month_number找到oldest_Id和Latest_id。
请建议,我是SQL的新手。
答案 0 :(得分:0)
这个答案假设是Microsoft SQL Server,但是对语法进行了调整,这可以适用于任何数据库类型,前提是它具有临时表,行计数和用户定义的变量(后者只是为了安全截止,以免你有一个循环)。此答案还假设源表格为#ExampleTable
,[New_ID]
列包含所有ID,并且只有相应的[Month_Number]
值适当时才应考虑较旧/较新的ID,例如LTE是较旧ID的“较新”ID [Month_Number]
。
基本上我想要的是制作两个临时表:第一个列出每个[ID]
以及[Old_ID]
的第一个[ID]
,第二个虽然是最后[New_ID]
:
-- 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]
;
#ID1
和#ID2
中的记录设置为首先引用自己。然后,对于循环中的每次传递,如果可用,则使用下一步更新ID的值。当没有别的事情要做时,迭代就会停止。
以下是每次传递中发生的事情:
@cutoff
变量只是为了防止这种情况永远循环,如果ID'A'引用旧ID'B'而ID'B'引用旧ID'A',举个例子。
这不是一种非常有效的方法,你可以通过一些练习做得更好:例如,将Oldie / Newie动作合二为一,但我会把它留给你。 :)