2012-05-11 18 views
0

せずにSQLでの階層レベルを合計:私はこのようになりますSQLサーバーのテーブルを持つカーソル

CREATE TABLE foo(
PlayerID BIGINT NOT NULL 
UpdatedAt DATETIME NOT NULL 
CurrencyBal MONEY NOT NULL) 

テーブルは30件のレコードが含まれています

1,2012-05-10,300 
2,2012-05-10,1100 
3,2012-05-10,10000 

を私はそのクエリを作成したいですプレイヤーの総数、クエリが実行された日付、および通貨層の内訳が返されるので、出力は常に1行だけ常に次のようになります。

Date: 2012-05-10 
Total Players: 3 
100 - 900 : 1 
999 - 1500 : 1 
9000 - MAX : 1 

カーソルを使ってティアレベルを合計する方法を知っていますが、私はちょうどそこにこれを行う方法がないかと思っています。 SELECT CASEを使用しようとすると、レコードごとに1行が取得されます。私はUpdatedAtでグループ化を試みて、同じことを返します。どんな助けもありがとう。

SELECT 
'0 - 10000' = COUNT(CASE WHEN CreditBalance >= 0 AND CreditBalance <= 10000 THEN 1 ELSE 0 END), 
'10001 - 20000' = COUNT(CASE WHEN CreditBalance >= 10001 AND CreditBalance <= 20000 THEN 1 ELSE 0 END), 
'20001 - 30000' = COUNT(CASE WHEN CreditBalance >= 20001 AND SUM(CreditBalance) <= 30000 THEN 1 ELSE 0 END), 
'30001 - 60000' = COUNT(CASE WHEN CreditBalance >= 30001 AND SUM(CreditBalance) <= 60000 THEN 1 ELSE 0 END), 
'60001 - 100000' = COUNT(CASE WHEN CreditBalance >= 60001 AND SUM(CreditBalance) <= 100000 THEN 1 ELSE 0 END), 
'100001 - 150000' = COUNT(CASE WHEN CreditBalance >= 100001 AND SUM(CreditBalance) <= 150000 THEN 1 ELSE 0 END), 
'150001 - 200000' = COUNT(CASE WHEN CreditBalance >= 150001 AND SUM(CreditBalance) <= 200000 THEN 1 ELSE 0 END), 
'200001 - 500000' = COUNT(CASE WHEN CreditBalance >= 200001 AND SUM(CreditBalance) <= 500000 THEN 1 ELSE 0 END), 
'500001 - 1000000' = COUNT(CASE WHEN CreditBalance >= 500001 AND SUM(CreditBalance) <= 1000000 THEN 1 ELSE 0 END), 
'1000001 - Max' = COUNT(CASE WHEN CreditBalance >= 1000001 THEN 1 ELSE 0 END), 
CONVERT(DATE,LastUpdateDate) AS [Day], 
SUM(CreditBalance) AS TotalDailyCurrency, 
COUNT(PlayerID) AS DailyActiveUsers, 
AVG(CreditBalance) AS AverageCreditsPerMAU 
FROM dbo.PlayerBalances 
WHERE CONVERT(DATE,LastUpdateDate) = CONVERT(DATE,GETUTCDATE()) 
GROUP BY LastUpdateDate 

と私は取得しています:メッセージ130、レベル15、状態1、行7 は、集計やサブクエリを含む式に集約関数を実行することはできません、次のクエリを用いて溶液1を使用して

+0

間隔のバランスがとれているユーザーが不足している可能性があるため、間隔が悪いです。私。 '10000.5'。 (row1) '<= 10000'と(row2)'> 10000' – Johan

答えて

1

私がしなければならなかったすべてはcase文からELSE 0を削除したように見えます。最終的な解決策は、次のようになります。

SELECT COUNT(CASE WHEN CreditBalance >= 0 
        AND CreditBalance <= 10000 THEN 1 
      END) AS '0-10000' , 
COUNT(CASE WHEN CreditBalance >= 10001 
        AND CreditBalance <= 20000 THEN 1 
      END) AS '10001 - 20000' , 
COUNT(CASE WHEN CreditBalance >= 20001 
        AND CreditBalance <= 30000 THEN 1 
      END) AS '20001 - 30000' , 
COUNT(CASE WHEN CreditBalance >= 30001 
        AND CreditBalance <= 60000 THEN 1 
      END) AS '30001 - 60000' , 
COUNT(CASE WHEN CreditBalance >= 60001 
        AND CreditBalance <= 100000 THEN 1 
      END) AS '60001 - 100000' , 
COUNT(CASE WHEN CreditBalance >= 100001 
        AND CreditBalance <= 150000 THEN 1 
      END) AS '100001 - 150000' , 
COUNT(CASE WHEN CreditBalance >= 150001 
        AND CreditBalance <= 200000 THEN 1 
      END) AS '150001 - 200000' , 
COUNT(CASE WHEN CreditBalance >= 200001 
        AND CreditBalance <= 500000 THEN 1 
      END) AS '200001 - 500000' , 
COUNT(CASE WHEN CreditBalance >= 500001 
        AND CreditBalance <= 1000000 THEN 1 
      END) AS '500001 - 1000000' , 
COUNT(CASE WHEN CreditBalance >= 1000001 THEN 1 
      END) AS '1000001 - MAX' 
FROM dbo.PlayerBalances 
GROUP BY CONVERT(DATE, LastUpdateDate) 
0
SELECT COUNT(CASE WHEN CurrencyBal >= x_1 and CurrencyBal < x_2 THEN 1 ELSE END), 
     COUNT(CASE WHEN CurrencyBal >= x_2 and CurrencyBal < x_3 THEN 1 ELSE END) 
    ...., 
    UpdatedAt, 
    Count(*) 
    FROM Table t 
    WHERE UpdatedAt = <yourdate> 
    GROUP BY UpdatedAt 

たり、テーブルティア(min_range、MAX_RANGE)であなたの階層を定義したい場合は、より良い方法

SELECT COUNT(CASE WHEN CurrencyBal >= min_range and CurrencyBal < max_range THEN 1 ELSE END), 
    min_range, 
    UpdatedAt 
    FROM Table t INNER JOIN Tier ti ON CurrencyBal >= min_range and CurrencyBal < max_range 
    WHERE UpdatedAt = <yourdate> 
    GROUP BY min_range,UpdatedAt 
+0

を試してみてください。解決策1を試してみたところ、エラーは – SSISPissesMeOff

1

別の代替とあなたのためのフィドルを手に入れました。どう考えているか教えてください。あなたのための

http://sqlfiddle.com/#!3/eed70/2

と別の代替これは、私はあなたが持っていたどのように多くの場合、最初は気付かなかった優れた拡張性があります。

http://sqlfiddle.com/#!3/eed70/4

+0

でした。最初のフィドルは結果を返さず、2番目のフィドルはすべてのレコードに対して1行を返します。上記のレベルに基づいて、すべてのヘッダー情報を取り除きたい場合は、カーソルなしで行うことができます。基本的には、選手がティアに分割された日付ごとに1つの行を戻します。私は、私はいつも私はカーソルを使用することに戻ることができますが、私はむしろそうではないと思います。 – SSISPissesMeOff

関連する問題