TSQL CTE 的(常见 table 表达式)错误
TSQL CTE's (common table expression) bug
我正在使用 Microsoft SQL Server 2008 (SP3) - 10.0.5520.0 (X64)
Windows NT 6.0(内部版本 6002:Service Pack 2)上的标准版(64 位)
描述:
[ORC_RESULT]
和 GROUPING_SELECT
是 CTE
table.
我有一个 CTE 的奇怪错误(常见 table 表达式)。
SELECT a.keysbor
--,gs.[rank]
FROM [ORC_RESULT] AS a inner JOIN GROUPING_SELECT AS gs
ON a.keysbor = gs.keysbor
WHERE gs.[RANK] = 1
ORDER BY a.keysbor
结果 36 行(无重复行)
SELECT a.keysbor
,gs.[rank]
FROM [ORC_RESULT] AS a inner JOIN GROUPING_SELECT AS gs
ON a.keysbor = gs.keysbor
WHERE gs.[RANK] = 1
ORDER BY a.keysbor
结果 29 行
问:为什么过滤器 gs.[RANK] = 1
仅在字段 gs.[rank]
存在于 SELECT
语句中时应用?
without gs.[rank] with gs.[rank] rank
10072002992443 10072002992443 1
10072002992444 10072002992444 1
10072002992445 10072002992445 1
10072002992446 10072002992446 1
10072002992447 10072002992447 1
10072002992448 10072002992448 1
10072002992449 10072002992449 1
10072002992450 10072002992450 1
10072002992451 10072002992451 1
10072002992452 10072002992452 1
10072002992453 10072002992453 1
10072002992454 10072002992454 1
10072002992455 10072002992455 1
10072002992456 10072002992456 1
10072002992457 10072002992457 1
10072002992458 10072002992458 1
10072002992459 10072002992459 1
10072002992460 10072002992460 1
10072002992461 2
10072002992462 2
10072002992463 2
10072002992464 2
10072002992465 2
10072002992466 2
10072002992467 2
10072002992736 10072002992736 1
10072002992866 10072002992866 1
10072002992867 10072002992867 1
10072002992868 10072002992868 1
10072002992869 10072002992869 1
10072002992870 10072002992870 1
10072002992871 10072002992871 1
10072002992872 10072002992872 1
10072002992873 10072002992873 1
10072002992874 10072002992874 1
10072002992875 10072002992875 1
我认为你的 [rank] 不是以确定的方式计算的,即
PARTITION BY A.[KEYKRT], A.[VIDSBR],A.[ORC_ID_ED] ORDER BY A.[ORC_ID_ED]
不唯一确定顺序,因此根据计划运算符,row_number() 可以将 1 分配给不同的行。
我给你一个例子,其中计划是相同的,但行的顺序不同,并且使用相同的输入数据你会得到 2 个不同的结果。
根据你在 SELECT 中放入的列,优化器构建不同的计划,并且你的 RANK 在不同的行中等于 1(对应于不同的 keysbor),因此在 keysbor 上连接时,返回不同的行数。
因此,在这两种情况下,都应用了过滤器 rank = 1,但 1 分配给了不同的行。
示例如下:
declare @t table( a int, b int, c int, primary key(c desc, b)); /*run it as it is, then uncomment PK and run again*/
insert into @t values
(1,1,1), (1,1,2), (1,1,3),
(1,2,1), (1,2,2), (1,2,3);
declare @t1 table( c int);
insert @t1 values (1);
with cte as (
select row_number() over (partition by a, b order by b) as rn,
a,
b,
c
from @t
group by a, b, c
)
select *
from cte c join @t1 t on c.c = t.c
where rn = 1;
如您所见,我总是有相同的输入,但在第一种情况下我没有声明主键,而在第二种情况下我声明了。
返回的行不同,但这并不意味着过滤器不起作用,它只是意味着在第一种情况下 rn = 1 被归因于 c = 1 的 2 行,但在第二种情况下 rn = 1 有两行 c =1 且 c=3。
我正在使用 Microsoft SQL Server 2008 (SP3) - 10.0.5520.0 (X64) Windows NT 6.0(内部版本 6002:Service Pack 2)上的标准版(64 位)
描述:
[ORC_RESULT]
和GROUPING_SELECT
是CTE
table.
我有一个 CTE 的奇怪错误(常见 table 表达式)。
SELECT a.keysbor
--,gs.[rank]
FROM [ORC_RESULT] AS a inner JOIN GROUPING_SELECT AS gs
ON a.keysbor = gs.keysbor
WHERE gs.[RANK] = 1
ORDER BY a.keysbor
结果 36 行(无重复行)
SELECT a.keysbor
,gs.[rank]
FROM [ORC_RESULT] AS a inner JOIN GROUPING_SELECT AS gs
ON a.keysbor = gs.keysbor
WHERE gs.[RANK] = 1
ORDER BY a.keysbor
结果 29 行
问:为什么过滤器 gs.[RANK] = 1
仅在字段 gs.[rank]
存在于 SELECT
语句中时应用?
without gs.[rank] with gs.[rank] rank
10072002992443 10072002992443 1
10072002992444 10072002992444 1
10072002992445 10072002992445 1
10072002992446 10072002992446 1
10072002992447 10072002992447 1
10072002992448 10072002992448 1
10072002992449 10072002992449 1
10072002992450 10072002992450 1
10072002992451 10072002992451 1
10072002992452 10072002992452 1
10072002992453 10072002992453 1
10072002992454 10072002992454 1
10072002992455 10072002992455 1
10072002992456 10072002992456 1
10072002992457 10072002992457 1
10072002992458 10072002992458 1
10072002992459 10072002992459 1
10072002992460 10072002992460 1
10072002992461 2
10072002992462 2
10072002992463 2
10072002992464 2
10072002992465 2
10072002992466 2
10072002992467 2
10072002992736 10072002992736 1
10072002992866 10072002992866 1
10072002992867 10072002992867 1
10072002992868 10072002992868 1
10072002992869 10072002992869 1
10072002992870 10072002992870 1
10072002992871 10072002992871 1
10072002992872 10072002992872 1
10072002992873 10072002992873 1
10072002992874 10072002992874 1
10072002992875 10072002992875 1
我认为你的 [rank] 不是以确定的方式计算的,即
PARTITION BY A.[KEYKRT], A.[VIDSBR],A.[ORC_ID_ED] ORDER BY A.[ORC_ID_ED]
不唯一确定顺序,因此根据计划运算符,row_number() 可以将 1 分配给不同的行。 我给你一个例子,其中计划是相同的,但行的顺序不同,并且使用相同的输入数据你会得到 2 个不同的结果。 根据你在 SELECT 中放入的列,优化器构建不同的计划,并且你的 RANK 在不同的行中等于 1(对应于不同的 keysbor),因此在 keysbor 上连接时,返回不同的行数。 因此,在这两种情况下,都应用了过滤器 rank = 1,但 1 分配给了不同的行。
示例如下:
declare @t table( a int, b int, c int, primary key(c desc, b)); /*run it as it is, then uncomment PK and run again*/
insert into @t values
(1,1,1), (1,1,2), (1,1,3),
(1,2,1), (1,2,2), (1,2,3);
declare @t1 table( c int);
insert @t1 values (1);
with cte as (
select row_number() over (partition by a, b order by b) as rn,
a,
b,
c
from @t
group by a, b, c
)
select *
from cte c join @t1 t on c.c = t.c
where rn = 1;
如您所见,我总是有相同的输入,但在第一种情况下我没有声明主键,而在第二种情况下我声明了。 返回的行不同,但这并不意味着过滤器不起作用,它只是意味着在第一种情况下 rn = 1 被归因于 c = 1 的 2 行,但在第二种情况下 rn = 1 有两行 c =1 且 c=3。