这是我正在处理的数据:
我想在sql中找到一种向黄色列添加数字的方法,它将按照以下方式对名称进行排名。
注意:这是最终的透视结果 - 在sql
表格中无需透视数据。
此排名由以下规则决定:
这是Idx
列中占位符为0的数据:
CREATE TABLE #values
(
Name varchar(5),
Idx int,
"Week" varchar(5),
Amount int
);
INSERT INTO #values
VALUES
('A',0,'WK1',3),
('T',0,'WK1',2),
('H',0,'WK1',1),
('P',0,'WK1',4),
('V',0,'WK1',6),
('N',0,'WK1',5),
('A',0,'WK2',2),
('F',0,'WK2',1),
('K',0,'WK2',3),
('P',0,'WK2',4),
('W',0,'WK2',7),
('V',0,'WK2',5),
('B',0,'WK2',6),
('A',0,'WK3',1),
('F',0,'WK3',2),
('T',0,'WK3',3),
('K',0,'WK3',4),
('W',0,'WK3',5),
('V',0,'WK3',6),
('N',0,'WK3',7),
('A',0,'WK4',2),
('F',0,'WK4',1),
('T',0,'WK4',5),
('K',0,'WK4',4),
('B',0,'WK4',6),
('A',0,'WK5',1),
('F',0,'WK5',2),
('T',0,'WK5',3),
('H',0,'WK5',4),
('K',0,'WK5',5);
这是我目前的尝试:
WITH
allData AS
(
SELECT Name,
"Week",
newRank = RANK() OVER (ORDER BY "Week" DESC,Amount)
FROM #values
)
,allData2 AS
(
SELECT *,
newRank2 = 1 / CONVERT(NUMERIC(18,10),newRank)
FROM allData
)
,allData3 AS
(
SELECT Name,
smRank = SUM(newRank2)
FROM allData2
GROUP BY Name
)
SELECT Name,
smRank,
rnk = RANK() OVER (ORDER BY smRank DESC)
INTO #RankA
FROM allData3;
UPDATE X
SET X.Idx = Y.rnk
FROM #values X
INNER JOIN #RankA Y ON
X.Name = Y.Name;
不幸的是,如果我转动结果,然后按Idx
列排序,则不符合我的目标。
答案 0 :(得分:2)
使用#values表,以下是如何对其进行透视(因为您提供的数据不是相同的表格格式),然后根据您的要求为索引分配值。
select *
, ROW_NUMBER() OVER(ORDER BY CASE WHEN wk5 IS NULL THEN 1 ELSE 0 END, wk5, CASE WHEN wk4 IS NULL THEN 1 ELSE 0 END, wk4, CASE WHEN wk3 IS NULL THEN 1 ELSE 0 END,wk3, CASE WHEN wk2 IS NULL THEN 1 ELSE 0 END,wk2, CASE WHEN wk1 IS NULL THEN 1 ELSE 0 END, wk1) AS new_index
from (
select * from #values
) p
PIVOT (
MAX(Amount)
FOR [week] IN (wk1, wk2, wk3, wk4, wk5)) AS pvt
动态使用52周
DECLARE @COLS AS NVARCHAR(MAX),
@QUERY AS NVARCHAR(MAX)
SELECT @COLS = STUFF(( SELECT distinct ','+QUOTENAME(C.[week])
FROM #values AS C
FOR XML PATH('')), 1, 1, '')
SET @QUERY = '
select *
, ROW_NUMBER() OVER(ORDER BY CASE WHEN wk5 IS NULL THEN 1 ELSE 0 END, wk5, CASE WHEN wk4 IS NULL THEN 1 ELSE 0 END, wk4, CASE WHEN wk3 IS NULL THEN 1 ELSE 0 END,wk3, CASE WHEN wk2 IS NULL THEN 1 ELSE 0 END,wk2, CASE WHEN wk1 IS NULL THEN 1 ELSE 0 END, wk1) AS new_index
from (
select * from #values
) p
PIVOT (
MAX(Amount)
FOR [week] IN (' + @cols+ ')) AS pvt'
EXEC(@QUERY)
答案 1 :(得分:2)
这是基于两个嵌套的ROW_NUMBER
:
select *,
row_number()
over (order by "Week" desc, amount)
from
(
select *,
row_number()
over (partition by name
order by "Week" desc, amount) as rn
from #values
) as dt
where rn = 1 -- for each name find the latest week and it's lowest number
如果两个名字共享同一周/金额怎么办?您可以考虑使用RANK
或DENSE_RANK
。