我如何根据多个条件进行计数

时间:2015-02-27 09:54:06

标签: sql select sql-server-2008-r2 counter

我目前有4列IdABC

 A     B    C
243    3    1
243    3    2
243    3    3
243    3    1
243    3    2
243    3    3
243    3    1
243    3    2
243    3    3
185    3    1
185    3    2
185    3    3
185    3    1
185    3    2
185    3    3
337    2    1
337    2    2
337    2    3
337    2    4
337    2    5
337    2    1
337    2    2
337    2    3
337    2    4
337    2    5
336    2    1
336    2    2
336    2    3
336    2    4
336    2    5

逻辑

  • 当前C为< 之前的C,然后计算 +1
  • 但当前A <> 之前的A然后重置计数

结果看起来像

 A     B    C  count
243    3    1    0
243    3    2    0
243    3    3    0
243    3    1    1
243    3    2    1
243    3    3    1
243    3    1    2
243    3    2    2
243    3    3    2
185    3    1    0
185    3    2    0
185    3    3    0
185    3    1    1
185    3    2    1
185    3    3    1
337    2    1    0
337    2    2    0
337    2    3    0
337    2    4    0
337    2    5    0
337    2    1    1
337    2    2    1
337    2    3    1
337    2    4    1
337    2    5    1
336    2    1    0
336    2    2    0
336    2    3    0
336    2    4    0
336    2    5    0

也可以使用B列来了解C

的最大值
  • 如果B == 3 C max将为3
  • 如果B == 2 C max将为5

我目前的尝试是

SELECT *, 
       1 + ((row_number() over(order by A, B, Id, C) - 1) / 
Case  B    WHEN 2 THEN 5
           ELSE 3 END)
 AS Test

哪个会做第1部分

  

当前C为< 之前的C然后计算 +1

但不是第2部分

1 个答案:

答案 0 :(得分:1)

这是一个可以在SQL Server 2008中使用的可能解决方案(没有LEAD / LAG)。主要思想是使用PARTITION BY A来“重置”计数器。 结果集具有中间列,因此您可以遵循逻辑。这很简单。

示例数据

DECLARE @T TABLE (ID int IDENTITY(1,1), [A] int, [B] int, [C] int);

INSERT INTO @T ([A], [B], [C])
VALUES
    (243, 3, 1),
    (243, 3, 2),
    (243, 3, 3),
    (243, 3, 1),
    (243, 3, 2),
    (243, 3, 3),
    (243, 3, 1),
    (243, 3, 2),
    (243, 3, 3),
    (185, 3, 1),
    (185, 3, 2),
    (185, 3, 3),
    (185, 3, 1),
    (185, 3, 2),
    (185, 3, 3),
    (337, 2, 1),
    (337, 2, 2),
    (337, 2, 3),
    (337, 2, 4),
    (337, 2, 5),
    (337, 2, 1),
    (337, 2, 2),
    (337, 2, 3),
    (337, 2, 4),
    (337, 2, 5),
    (336, 2, 1),
    (336, 2, 2),
    (336, 2, 3),
    (336, 2, 4),
    (336, 2, 5);

查询

WITH
CTE_Test
AS
(
    SELECT
        ID, A, B, C,
        1 + ((row_number() over(order by A, B, Id, C) - 1) / 
        Case B WHEN 2 THEN 5 ELSE 3 END) AS Test
    FROM @T
)
,CTE_Min
AS
(
    SELECT
        ID, A, B, C, Test
        , MIN(Test) OVER(PARTITION BY A) AS MinTest
    FROM CTE_Test
)
SELECT
    ID, A, B, C, Test, MinTest
    , Test - MinTest AS FinalCount
FROM CTE_Min
ORDER BY ID;

结果集

ID    A      B    C    Test    MinTest    FinalCount
1     243    3    1    3       3          0
2     243    3    2    3       3          0
3     243    3    3    3       3          0
4     243    3    1    4       3          1
5     243    3    2    4       3          1
6     243    3    3    4       3          1
7     243    3    1    5       3          2
8     243    3    2    5       3          2
9     243    3    3    5       3          2
10    185    3    1    1       1          0
11    185    3    2    1       1          0
12    185    3    3    1       1          0
13    185    3    1    2       1          1
14    185    3    2    2       1          1
15    185    3    3    2       1          1
16    337    2    1    5       5          0
17    337    2    2    5       5          0
18    337    2    3    5       5          0
19    337    2    4    5       5          0
20    337    2    5    5       5          0
21    337    2    1    6       5          1
22    337    2    2    6       5          1
23    337    2    3    6       5          1
24    337    2    4    6       5          1
25    337    2    5    6       5          1
26    336    2    1    4       4          0
27    336    2    2    4       4          0
28    336    2    3    4       4          0
29    336    2    4    4       4          0
30    336    2    5    4       4          0
相关问题