我在 SQL Server 2008 中有一个表,我需要其中一列的交替值,比如列 alt
.该列中的重复项总是需要相同的值,因此我正在考虑使用 dense_rank
此列的函数 alt
通过 % 2。
但是该表中还有邮政编码,我需要在分配交替值之前对数据进行排序。
所以基本上在基于列 alt
的交替值之后当数据按邮政编码排序时已经分配了交替值确实需要交替(当然除了“alt”表中的重复项)。
目前我得到的结果是 alt
值确实会得到交替值,但是当按邮政编码排序时,我有例如0,0,0 通过这是问题的dense_rank 函数。
我尝试使用临时表,但没有得到预期的结果
select * into #txy ordered by zip
然后在该表上执行desk_rank,因为不能保证临时表的顺序。
任何想法都非常感谢!
干杯,
斯蒂沃
编辑:
示例代码:
CREATE TABLE [xy.TestTable](
[BaseForAlternatingValue] [char](10),
[zip] [varchar](5)
) ON [PRIMARY]
GO
INSERT INTO [xy.TestTable]
([BaseForAlternatingValue]
,[zip])
VALUES
('cccccccccc','99999'),
('bbbbbbbbbb','22222'),
('aaaaaaaaaa','12345'),
('dddddddddd','33333'),
('aaaaaaaaaa','12345'),
('bbbbbbbbbb','22222')
GO
select (DENSE_RANK() OVER (ORDER BY BaseForAlternatingValue)) % 2 as AlternatingValue
, BaseForAlternatingValue
, zip
from [xy.TestTable]
order by zip
Result:
AlternatingValue BaseForAlternatingValue zip
1 aaaaaaaaaa 12345
1 aaaaaaaaaa 12345
0 bbbbbbbbbb 22222
0 bbbbbbbbbb 22222
0 dddddddddd 33333
1 cccccccccc 99999
现在的问题是,当按邮政编码排序时,以下列都包含与交替值相同的值 (0)。当按邮政编码排序时,结果应该真的有交替值,但这些交替值应该基于 BaseForAlternatingValue 列。
0 bbbbbbbbbb 22222
0 dddddddddd 33333
预期的结果应该是:
AlternatingValue BaseForAlternatingValue zip
1 aaaaaaaaaa 12345
1 aaaaaaaaaa 12345
0 bbbbbbbbbb 22222
0 bbbbbbbbbb 22222
1 dddddddddd 33333
0 cccccccccc 99999
最后两个结果行的最后一个 AlternatingValue 不同:Alternating Value 需要在不同的邮政编码之间交替。之前倒数第三行为 0,倒数第二行也为 0。
至于下面 Mikael 的问题,“如果你添加了行 ('cccccccccc','12345'),那么预期的输出会是什么?”
预期的输出将是:
AlternatingValue BaseForAlternatingValue zip
1 aaaaaaaaaa 12345
1 aaaaaaaaaa 12345
0 cccccccccc 12345
1 bbbbbbbbbb 22222
1 bbbbbbbbbb 22222
0 dddddddddd 33333
0 cccccccccc 99999
所以总而言之:我需要 BaseForAlternatingValue 列的交替值,但是当按邮政编码排序时,这种交替应该是可见的。 (并且 BaseForAlternatingValue 中的重复项需要相同的“交替”值)
----------------
最后我找到了一个更简单也相对不错的解决方案:
1) 使用带有 insert into 和 order by 的临时表并使用 id 值(id 值将反射(reflect) order by 子句)
2) 找出给定 BaseForAlternatingValue 的最小 id
3) 找出 id 小于该值的不同 BaseForAlternatingValues 的计数
最佳答案
尝试使用 ROW_NUMBER
作为 DENSE_RANK
的直接替代品. DENSE_RANK
将给多行相同的值,它们并列排名 - ROW_NUMBER
将不会。
DENSE_RANK
引用
ROW_NUMBER
引用
编辑
这很丑陋,但似乎产生了正确的结果。
第一个 CTE 确定行的输出顺序并计算“交替值”。
第二个确定每个 BaseForAlternatingValue
的第一个实例在输出结果集中。
输出查询以正确的顺序返回行,并为每个 BaseForAlternatingValue
返回第一个“交替值”。
;WITH cte
AS
(
SELECT BaseForAlternatingValue, zip,
ROW_NUMBER() OVER (ORDER BY zip,BaseForAlternatingValue)AS rn,
DENSE_RANK() OVER (ORDER BY zip,BaseForAlternatingValue) % 2 AS av
FROM [xy.TestTable]
)
,rnCTE
AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY BaseForAlternatingValue ORDER BY rn) AS rn2
FROM cte
)
SELECT rn.av AS AlternatingValue,
r.BaseForAlternatingValue, r.zip
FROM cte r
JOIN rnCTE rn
ON rn.BaseForAlternatingValue = r.BaseForAlternatingValue
AND rn.rn2 =1
ORDER BY zip, BaseForAlternatingValue
关于sql-server-2008 - SQL Server : How to use dense_rank on one column, 基于另一列的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11556125/