我正试图解决这个问题;我有一张这样的桌子:
SELECT [ID], [STRING] FROM Test
ID STRING
38 Hi 38
39 Hi 39
42 Hi 42
46 Hi 46
47 Hi 47
49 Hi 49
TDL:
CREATE TABLE #Test ([ID] int,[STRING] varchar(50)) ;
INSERT INTO #Test
([ID], [STRING])
VALUES
(38, 'Hi 38'),
(39, 'Hi 39'),
(42, 'Hi 42'),
(46, 'Hi 46'),
(47, 'Hi 47'),
(49, 'Hi 49')
;
ID
为INT
,STRING
为VARCHAR(50)
,我应该编写一个新的SELECT查询来获得此结果:
ID STRING
38 Hi 38
39 Hi 39
40 Hi 39
41 Hi 39
42 Hi 42
43 Hi 42
44 Hi 42
45 Hi 42
46 Hi 46
47 Hi 47
48 Hi 47
49 Hi 49
填写渐进式ID并使用STRING
的先前值作为新ID。
我尝试过使用CTE但没有结果。
答案 0 :(得分:1)
在这里,我通过将差异复制到多个行来生成差异行,将它们转换为xml,外部应用实际表格。
DECLARE @Table TABLE
(
ID INT ,
STRING VARCHAR(50)
)
INSERT INTO @Table
VALUES ( 38, 'Hi 38' )
, ( 39, 'Hi 39' )
, ( 42, 'Hi 42' )
, ( 46, 'Hi 46' )
, ( 47, 'Hi 47' )
, ( 49, 'Hi 49' );
WITH cte
AS ( SELECT ID ,
STRING ,
CAST(REPLICATE('<k>1</k>',
LEAD(ID) OVER ( ORDER BY ID ) - ID) AS XML) AS x
FROM @Table
),
cte2
AS ( SELECT a.ID ,
a.STRING ,
ROW_NUMBER() OVER ( PARTITION BY a.ID ORDER BY ID )
- 1 AS ID2
FROM cte AS a
OUTER APPLY x.nodes('/k') t ( x )
)
SELECT ID + ID2 AS ID ,
STRING
FROM cte2 AS a
ORDER BY a.ID
答案 1 :(得分:1)
对于SQL Server 2008
;WITH id_rn ( id, string, rn )
AS ( SELECT id ,
string ,
ROW_NUMBER() OVER ( ORDER BY id )
FROM t
),
id_min_max ( min_id, max_id )
AS ( SELECT MIN(id) ,
MAX(id)
FROM t
),
rows ( n )
AS ( SELECT min_id
FROM id_min_max
UNION ALL
SELECT n + 1
FROM rows
WHERE n < ( SELECT max_id
FROM id_min_max
)
)
SELECT COALESCE(r.n, i1.id) AS id ,
i1.string AS string
FROM id_rn AS i1
LEFT JOIN id_rn AS i2 ON i2.rn = i1.rn + 1
LEFT JOIN rows AS r ON r.n BETWEEN i1.id AND i2.id - 1
ORDER BY id
OPTION ( MAXRECURSION 0 );
;WITH id_occ ( id, string, #id_missing_occ )
AS ( SELECT id ,
string ,
LEAD(id) OVER ( ORDER BY id ) - id - 1
FROM t
),
max_id_occ ( #max_generated_rows )
AS ( SELECT MAX(#id_missing_occ) + 1
FROM id_occ
),
rows ( n )
AS ( SELECT 1
UNION ALL
SELECT n + 1
FROM rows
WHERE n < ( SELECT #max_generated_rows
FROM max_id_occ
)
)
SELECT id + COALESCE(n - 1, 0) ,
string
FROM id_occ AS i
LEFT JOIN rows AS r ON r.n <= i.#id_missing_occ + 1
AND #id_missing_occ > 0
OPTION ( MAXRECURSION 0 );
答案 2 :(得分:0)
您必须使用足够大的Tally表来覆盖表中找到的所有ID
值范围。使用this source中的Tally表,查询可能如下所示:
WITH Tally (n) AS
(
-- 1000 rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
), Min_Max_CTE(min_id, max_id) AS
(
SELECT MIN(ID) AS min_id, MAX(ID) AS max_id
FROM mytable
)
SELECT ID, MAX(STRING) OVER (PARTITION BY grp) AS STRING
FROM (
SELECT t1.n AS ID, t3.STRING,
MAX(t3.ID) OVER (ORDER BY t1.n) AS grp
FROM Tally As t1
CROSS JOIN Min_Max_CTE AS t2
LEFT JOIN mytable AS t3 ON t3.ID = t1.n
WHERE t1.n BETWEEN t2.min_id AND t2.max_id) AS t
注意:上述查询适用于SQL Server 2012 +。
答案 3 :(得分:0)
试试这个:
IClass2