Dmi*_*sev 3 t-sql sql-server sql-server-2008 sql-server-2008-r2 cross-apply
有一个简单的代码。我一直以为ROW_NUMBER外部和CROSS APPLY子句中的那个都应该生成相同的输出(在我的示例中,我例外rn = crn)。你能解释为什么不是那样吗?
CREATE TABLE #tmp ( id INT, name VARCHAR(200) );
INSERT INTO #tmp
VALUES ( 1, 'a' ),
( 2, 'a' ),
( 3, 'a' ),
( 4, 'b' ),
( 5, 'b' ),
( 6, 'c' ),
( 7, 'a' );
SELECT name,
ROW_NUMBER() OVER ( PARTITION BY name ORDER BY id ) AS rn,
a.crn
FROM #tmp
CROSS APPLY (
SELECT ROW_NUMBER() OVER ( PARTITION BY name ORDER BY id ) AS crn
) a;
Run Code Online (Sandbox Code Playgroud)
输出:
name rn crn
a 1 1
a 2 1
a 3 1
a 4 1
b 1 1
b 2 1
c 1 1
Run Code Online (Sandbox Code Playgroud)
请注意,APPLY使用主查询中的字段作为参数。
SELECT ROW_NUMBER() OVER ( PARTITION BY name ORDER BY id ) AS crn
Run Code Online (Sandbox Code Playgroud)
上述查询没有子句FROM。所以它将nameand视为id文字。为了说明这一点,对于 的第一行#tmp,结果查询是CROSS APPLY:
SELECT ROW_NUMBER() OVER ( PARTITION BY (SELECT 'a') ORDER BY (SELECT 1)) AS crn
Run Code Online (Sandbox Code Playgroud)
返回:
crn
--------------------
1
Run Code Online (Sandbox Code Playgroud)
CROSS APPLY这是你对每一行的结果。
为了达到预期的结果:
SELECT
t.name,
ROW_NUMBER() OVER ( PARTITION BY t.name ORDER BY t.id ) AS rn,
a.crn
FROM #tmp t
CROSS APPLY(
SELECT id, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id ) AS crn
FROM #tmp
) a
WHERE t.id = a.id
Run Code Online (Sandbox Code Playgroud)