4

我在 SQL Server 2008 中有一个表,我需要为一列交替值,比如 column alt。该列中的重复项始终需要相同的值,因此我正在考虑通过 % 2使用dense_rank该列的函数。alt

但是该表中也有邮政编码,我需要在分配交替值之前对数据进行排序。

所以基本上在基于列的交替值alt已经分配之后,当数据然后按邮政编码排序时,交替值确实需要交替(当然除了“alt”表中的重复项)。

目前,我得到一个结果,其中alt值确实得到了交替值,但是当按邮政编码排序时,我通过 dense_rank 函数获得了例如 0,0,0 的序列,这是问题所在。

我尝试使用临时表,但没有得到预期的结果

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 的问题,“如果你有 add row ('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)使用带有插入和排序的临时表并使用id值(id值将反映order by子句)2)找出给定BaseForAlternatingValue的最小id 3) 找出 id 小于的不同 BaseForAlternatingValues 的计数

4

2 回答 2

0

尝试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
于 2012-07-19T07:59:22.650 回答
0

我知道现在这无关紧要,因为这个问题早已得到解决。

您可以使用单个 cte 和连接来执行此操作:

with mins as (
    select min(zip) min_zip,
        BaseForAlternatingValue
    from xy.TestTable
    group by BaseForAlternatingValue
)
select dense_rank() over (order by m.min_zip, t.BaseForAlternatingValue) % 2 AlternatingValue,
    t.BaseForAlternatingValue,
    t.zip
from xy.TestTable t
join mins m on m.BaseForAlternatingValue = t.BaseForAlternatingValue
order by t.zip, t.base;

具有单个 cte 的 SQL Server 2012 的替代解决方案:

with mins as (
    select min(zip) over (partition by BaseForAlternatingValue) min_zip,
        BaseForAlternatingValue,
        zip
    from xy.TestTable
)
select dense_rank() over (order by min_zip, BaseForAlternatingValue) % 2 AlternatingValue,
    BaseForAlternatingValue,
    zip
from mins
order by zip;

这个想法是,如果你能保证永远不会有 2 个相同的 base 不同的 zip,你可以先按 zip 排序,然后再按 base 排序。由于您的订购仅取决于每个底座的最小 zip,因此您可以使用min()- 或在 2012min() over (partition by)年删除join.

于 2016-01-13T15:37:03.397 回答