考虑我有下表。
ID value
1 100
2 200
3 200
5 250
6 1
我有以下查询,其结果如下。我想从rank函数中排除值200,但仍然必须返回该行。
SELECT
CASE WHEN Value = 200 THEN 0
ELSE DENSE_RANK() OVER ( ORDER BY VALUE DESC)
END AS RANK,
ID,
VALUE
FROM @table
RANK ID VALUE
1 5 250
0 2 200
0 3 200
4 1 100
5 6 1
但我希望结果如下。怎么实现呢?
RANK ID VALUE
1 5 250
0 2 200
0 3 200
2 1 100
3 6 1
答案 0 :(得分:6)
如果VAL列不可为空,则考虑NULL是ORDER BY .. DESC
select *, dense_rank() over (order by nullif(val,200) desc) * case val when 200 then 0 else 1 end
from myTable
order by val desc;
答案 1 :(得分:0)
目前没有办法在密集排名中排除Val,除非你在where子句中过滤..这就是原因,你得到的结果
sortSelect(document.getElementsByName("options"));
您需要过滤一次然后再进行联合
RANK ID VALUE
1 5 250
0 2 200
0 3 200
4 1 100
5 6 1
答案 2 :(得分:0)
你也可以试试这个:
SELECT ISNULL(R, 0) AS Rank ,t.id ,t.value
FROM tbl1 AS t
LEFT JOIN ( SELECT id ,DENSE_RANK() OVER ( ORDER BY value DESC ) AS R
FROM dbo.tbl1 WHERE value <> 200
) AS K
ON t.id = K.id
ORDER BY t.value DESC
答案 3 :(得分:0)
您可以将排名拆分为对要包含/排除在排名中的值的单独查询以及UNION ALL
结果,如下所示:
独立可执行示例:
CREATE TABLE #temp ( [ID] INT, [value] INT );
INSERT INTO #temp
( [ID], [value] )
VALUES ( 1, 100 ),
( 2, 200 ),
( 3, 200 ),
( 5, 250 ),
( 6, 1 );
SELECT *
FROM ( SELECT 0 RANK ,
ID ,
value
FROM #temp
WHERE value = 200 -- set rank to 0 for value = 200
UNION ALL
SELECT DENSE_RANK() OVER ( ORDER BY value DESC ) AS RANK ,
ID ,
value
FROM #temp
WHERE value != 200 -- perform ranking on records != 200
) t
ORDER BY value DESC ,
t.ID
DROP TABLE #temp
<强>产地:强>
RANK ID value
1 5 250
0 2 200
0 3 200
2 1 100
3 6 1
如果需要,您可以修改语句末尾的顺序,我将其设置为产生您想要的结果。
答案 4 :(得分:0)
原始问题中的解决方案实际上非常接近。只需在density_rank上添加一个分区子句即可达到目的。
SELECT CASE
WHEN VALUE = 200 THEN 0
ELSE DENSE_RANK() OVER(
PARTITION BY CASE WHEN VALUE = 200 THEN 0 ELSE 1 END
ORDER BY VALUE DESC
)
END AS RANK
,ID
,VALUE
FROM @table
ORDER BY VALUE DESC;
“ partition by”会为density_rank创建单独的组,以便对这些组分别执行顺序。从本质上讲,这意味着您同时创建两个等级,一个用于没有200值的组,一个用于仅具有200值的组。在“ case when”情况下,后者应设置为0。
独立的可执行示例:
DECLARE @table TABLE
(
ID INT NOT NULL PRIMARY KEY
,VALUE INT NULL
)
INSERT INTO @table
(
ID
,VALUE
)
SELECT 1, 100
UNION SELECT 2, 200
UNION SELECT 3, 200
UNION SELECT 5, 250
UNION SELECT 6, 1;
SELECT CASE
WHEN VALUE = 200 THEN 0
ELSE DENSE_RANK() OVER(
PARTITION BY CASE WHEN VALUE = 200 THEN 0 ELSE 1 END
ORDER BY VALUE DESC
)
END AS RANK
,ID
,VALUE
FROM @table
ORDER BY VALUE DESC;
RANK ID VALUE
1 5 250
0 2 200
0 3 200
2 1 100
3 6 1