NTILE 是否适用于浮点数?

Thr*_*onk 4 sql-server t-sql

我试图在我的 PARTITION BY 子句中使用浮点数据类型对我的数据使用 NTILE。请原谅人为的例子,但我认为说明我的问题和困惑的最好方法是通过以下代码:

CREATE TABLE Test 
(
    Cash float NOT NULL,
    Number int NOT NULL
)
GO

INSERT INTO TEST VALUES(1.05,1);
INSERT INTO TEST VALUES(1.368,1);
INSERT INTO TEST VALUES(0.775,1);
INSERT INTO TEST VALUES(1.699,1);
INSERT INTO TEST VALUES(1.599,1);
INSERT INTO TEST VALUES(0.80,1);
INSERT INTO TEST VALUES(0.80,1);
INSERT INTO TEST VALUES(0.994,1);
INSERT INTO TEST VALUES(0.848,1);
INSERT INTO TEST VALUES(0.675,1);
INSERT INTO TEST VALUES(0.575,1);
INSERT INTO TEST VALUES(12.998,1);
INSERT INTO TEST VALUES(1.999,1);
INSERT INTO TEST VALUES(0.65,1);
INSERT INTO TEST VALUES(0.80,1);
INSERT INTO TEST VALUES(2.60,1);

SELECT CASH, 
    NTILE(3) OVER (PARTITION BY Cash ORDER BY Cash) AS Trio
    INTO #Test
FROM Test
Run Code Online (Sandbox Code Playgroud)

我本来希望分组是这样的:

0.575   1
0.65    1
0.675   1
0.775   1
0.8     1
0.8     2
0.8     2
0.848   2
0.994   2
1.05    2
1.368   3
1.599   3
1.699   3
1.999   3
2.6     3
12.998  3
Run Code Online (Sandbox Code Playgroud)

但相反,结果集如下所示:

CASH    Trio
0.575   1
0.65    1
0.675   1
0.775   1
0.8     1
0.8     2
0.8     3
0.848   1
0.994   1
1.05    1
1.368   1
1.599   1
1.699   1
1.999   1
2.6     1
12.998  1
Run Code Online (Sandbox Code Playgroud)

当按组应用 max 和 min 时,范围分组看起来很奇怪

SELECT 
    MAX(CASH), MIN(CASH), Trio
FROM #Test
GROUP BY Trio

MAX     MIN     TRIO
12.998  0.575   1
0.8     0.8     2
0.8     0.8     3
Run Code Online (Sandbox Code Playgroud)

谁能解释这里发生了什么?

Kin*_*hah 5

NTILE 函数将输入集分解为不同N equal大小的组。要确定每个组中有多少行,SQL Server 必须首先确定输入集中的总行数。

如果 NTILE 函数包含PARTITION BY子句,则 SQL Server 必须分别计算每个分区中的行数。一旦我们知道每个分区中的行数,我们就可以将 NTILE 函数写为

NTILE(N) := (N * (ROW_NUMBER() - 1) / COUNT(*)) + 1
Run Code Online (Sandbox Code Playgroud)

其中COUNT(*)是每个分区中的行数。

综上所述,下面将解释:

select *, (3*(RowNumber-1)/Cnt)+1 AS MyNTile
from 
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY Cash ORDER BY cash) AS RowNumber,
        COUNT(*) OVER (PARTITION BY Cash ) AS Cnt,
        NTILE(3) OVER (PARTITION BY Cash ORDER BY Cash) AS NTile,
        NTILE(3) OVER (ORDER BY Cash) AS WholeTableNtile

    FROM Test
) T
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

请参阅:排名函数:RANK、DENSE_RANK 和 NTILE