4

SQL Server 2008にテーブルがあり、1つの列、た​​とえば列に交互の値が必要です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

最後の2つの結果行の最後のAlternatingValueは異なります。AlternatingValueは異なる郵便番号を交互に使用する必要があります。前は、最後から3番目の行が0で、最後から2番目の行が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)ID値に挿入して順序付けする一時テーブルを使用し、id値を使用します(id値はorder by句を反映します)2)指定されたBaseForAlternatingValueの最小IDを見つけます3)それよりも小さいIDを持つ個別のBaseForAlternatingValuesの数を見つける

4

2 に答える 2

0

ROW_NUMBERの直接の代替として使用してみてくださいDENSE_RANKDENSE_RANK複数の行に同じ値を与え、ランクを結びます-しROW_NUMBERません。

DENSE_RANKリファレンス ROW_NUMBERリファレンス

編集

これは醜いですが、正しい結果が得られるようです。最初のCTEは、行の出力順序を決定し、「代替値」を計算します。2番目は、出力結果セット内
のそれぞれの最初のインスタンスを決定します。 出力クエリは、各行の最初の「代替値」を含む正しい順序で行を返します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を使用したSQLServer2012の代替ソリューション:

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;

異なるzipを持つ同じベースが2つ存在しないことを保証できる場合は、最初にzip、次にbaseの順にdense_rankを並べ替えることができます。注文は各ベースの最小zipにのみ依存するため、-または2012年にを使用してそれを取得できmin()ます。min() over (partition by)join

于 2016-01-13T15:37:03.397 に答える