表创建
SET NOCOUNT ON;
USE tempdb;
GO
IF OBJECT_ID('dbo.Sales') IS NOT NULL
DROP TABLE dbo.Sales;
GO
CREATE TABLE dbo.Sales
(
empid VARCHAR(10) NOT NULL PRIMARY KEY,
mgrid VARCHAR(10) NOT NULL,
qty INT NOT NULL
);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('A', 'Z', 300);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('B', 'X', 100);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('C', 'X', 200);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('D', 'Y', 200);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('E', 'Z', 250);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('F', 'Z', 300);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('G', 'X', 100);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('H', 'Y', 150);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('I', 'X', 250);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('J', 'Z', 100);
INSERT INTO dbo.Sales(empid, mgrid, qty) VALUES('K', 'Y', 200);
CREATE INDEX idx_qty_empid ON dbo.Sales(qty, empid);
CREATE INDEX idx_mgrid_qty_empid ON dbo.Sales(mgrid, qty, empid);
GO
-- Querying the Sales table
SELECT * FROM dbo.Sales;
返回行号 ,一般方法
-- Row number, unique sort column
SELECT empid,
(SELECT COUNT(*)
FROM dbo.Sales AS S2
WHERE S2.empid <= S1.empid) AS rownum
FROM dbo.Sales AS S1
ORDER BY empid;
查询语句
-- Rank and dense rank
SELECT empid, qty,
RANK() OVER(ORDER BY qty) AS rnk,
DENSE_RANK() OVER(ORDER BY qty) AS drnk
FROM dbo.Sales
ORDER BY qty;
Rank表排名有间断,Dense_Rank无间断
替代方法:
SELECT empid, qty,
(SELECT COUNT(*) FROM dbo.Sales AS S2
WHERE S2.qty < S1.qty) + 1 AS rnk,
(SELECT COUNT(DISTINCT qty) FROM dbo.Sales AS S2
WHERE S2.qty < S1.qty) + 1 AS drnk
FROM dbo.Sales AS S1
ORDER BY qty;
NTLINE指定分组数量
-- NTILE
SELECT empid, qty,
NTILE(3) OVER(ORDER BY qty, empid) AS tile
FROM dbo.Sales
ORDER BY qty, empid;
-- Descriptive Tiles
SELECT empid, qty,
CASE NTILE(3) OVER(ORDER BY qty, empid)
WHEN 1 THEN 'low'
WHEN 2 THEN 'meduim'
WHEN 3 THEN 'high'
END AS lvl
FROM dbo.Sales
ORDER BY qty, empid;
获取每个类别对应的范围
-- Ranges of Quantities Corresponding to each Category
WITH Tiles AS
(
SELECT empid, qty,
NTILE(3) OVER(ORDER BY qty, empid) AS tile
FROM dbo.Sales
)
SELECT tile, MIN(qty) AS lb, MAX(qty) AS hb
FROM Tiles
GROUP BY tile
ORDER BY tile;