0

我有一个如下所示的 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 分组并返回相同的东西。任何帮助,将不胜感激。

将解决方案 1 与以下查询一起使用:

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 行无法对包含聚合或子查询的表达式执行聚合函数。

4

3 回答 3

1

有另一种选择和小提琴给你。让我知道你的想法。

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

和你的另一种选择,这可能会更好地扩展我一开始并没有注意到你有多少案例。

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

于 2012-05-11T01:59:04.017 回答
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)
于 2012-05-11T08:26:31.673 回答
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
于 2012-05-11T00:18:42.777 回答