我有一个查询在查询财务数字和标志是否达到目标。我有一个列,如果命中目标,则填充1,如果未命中目标,则为NULL。这是一个简单的CASE语句。
我需要能够计算该列中有多少连续的行填充有1,然后在击中NULL时停止计数,然后从下一个非null开始重新计数。
我尝试了所有可能想到的“ COUNT(*)OVER”组合,但都没有给我所需的结果。
我会发布整个查询,因为它不会太长-
SELECT
*,
CASE
WHEN zzz.Flag_hit_Target IS NOT NULL THEN COUNT(*) OVER (PARTITION BY zzz.Flag_hit_Target ORDER BY CAST(zzz.Close_month as DATE) DESC)
ELSE NULL
END AS Counter
FROM
(
SELECT
zz.Close_month,
SUM(MRP) as Total_MRP,
zz.Target,
CASE
WHEN SUM(MRP) >= zz.Target THEN 1
ELSE NULL
END AS Flag_hit_target
FROM
(
SELECT
Opp.id,
opp.MRP__c as MRP,
1500 as Target,
CONCAT(DATENAME(month, Closedate), ' ', DATEPART(year, Closedate)) as Close_month
FROM Table1 as Opp WITH (NOLOCK)
WHERE OPP_type__c = 'Opp Type 1'
AND Appointment_setter1__c = 'Person 1'
AND Stagename = 'Closed (Won)'
) as zz
GROUP BY zz.Close_month, zz.Target
) as zzz
ORDER by CAST(zzz.Close_month as DATE) desc
通过此操作,我得到以下结果-
+----------------+-----------------+---------+
| Close_month | Flag_hit_target | Counter |
+----------------+-----------------+---------+
| June 2019 | NULL | NULL |
| April 2019 | NULL | NULL |
| March 2019 | 1 | 1 |
| February 2019 | NULL | NULL |
| January 2019 | 1 | 2 |
| November 2018 | NULL | NULL |
| October 2018 | NULL | NULL |
| September 2018 | NULL | NULL |
| July 2018 | NULL | NULL |
| June 2018 | 1 | 3 |
| May 2018 | NULL | NULL |
| April 2018 | 1 | 4 |
| March 2018 | NULL | NULL |
| February 2018 | 1 | 5 |
| January 2018 | 1 | 6 |
| December 2017 | 1 | 7 |
| October 2017 | NULL | NULL |
| September 2017 | 1 | 8 |
| August 2017 | 1 | 9 |
| July 2017 | 1 | 10 |
| June 2017 | 1 | 11 |
| May 2017 | NULL | NULL |
| April 2017 | 1 | 12 |
| March 2017 | NULL | NULL |
| February 2017 | 1 | 13 |
| January 2017 | 1 | 14 |
+----------------+-----------------+---------+
我追求的结果如下(注意最后一栏)-
+----------------+-----------------+---------+
| Close_month | Flag_hit_target | Counter |
+----------------+-----------------+---------+
| June 2019 | NULL | NULL |
| April 2019 | NULL | NULL |
| March 2019 | 1 | 1 |
| February 2019 | NULL | NULL |
| January 2019 | 1 | 1 |
| November 2018 | NULL | NULL |
| October 2018 | NULL | NULL |
| September 2018 | NULL | NULL |
| July 2018 | NULL | NULL |
| June 2018 | 1 | 1 |
| May 2018 | NULL | NULL |
| April 2018 | 1 | 1 |
| March 2018 | NULL | NULL |
| February 2018 | 1 | 3 |
| January 2018 | 1 | 2 |
| December 2017 | 1 | 1 |
| October 2017 | NULL | NULL |
| September 2017 | 1 | 4 |
| August 2017 | 1 | 3 |
| July 2017 | 1 | 2 |
| June 2017 | 1 | 1 |
| May 2017 | NULL | NULL |
| April 2017 | 1 | 1 |
| March 2017 | NULL | NULL |
| February 2017 | 1 | 2 |
| January 2017 | 1 | 1 |
+----------------+-----------------+---------+
谢谢!
答案 0 :(得分:2)
一种解决方案是对所有记录使用ROW_NUMBER
,然后对每个日期减去最后ROW_NUMBER
条记录的NULL
值。
设置:
IF OBJECT_ID('tempdb..#Test') IS NOT NULL
DROP TABLE #Test
CREATE TABLE #Test (
Date DATE,
Flag BIT)
INSERT INTO #Test (
Date,
Flag)
VALUES
('2019-09-01', NULL),
('2019-08-01', NULL),
('2019-07-01', 1),
('2019-06-01', NULL),
('2019-05-01', 1),
('2019-04-01', NULL),
('2019-03-01', NULL),
('2019-02-01', NULL),
('2019-01-01', 1),
('2018-12-01', NULL),
('2018-11-01', 1),
('2018-10-01', NULL),
('2018-09-01', 1),
('2018-08-01', 1),
('2018-07-01', 1),
('2018-06-01', NULL),
('2018-05-01', 1),
('2018-04-01', 1),
('2018-03-01', 1),
('2018-02-01', 1),
('2018-01-01', NULL)
解决方案:
;WITH DataWithRowNumber AS
(
SELECT
T.*,
RowNumber = -1 + ROW_NUMBER() OVER (ORDER BY T.Date)
FROM
#Test AS T
)
SELECT
D.Date,
D.Flag,
D.RowNumber,
M.MaxPreviousNullRowNumber,
RowNumberRest = D.RowNumber - M.MaxPreviousNullRowNumber,
Counter = CASE WHEN D.Flag IS NOT NULL THEN D.RowNumber - M.MaxPreviousNullRowNumber END
FROM
DataWithRowNumber AS D
OUTER APPLY (
SELECT
MaxPreviousNullRowNumber = MAX(R.RowNumber)
FROM
DataWithRowNumber AS R
WHERE
R.Date < D.Date AND
R.Flag IS NULL) AS M
ORDER By
D.RowNumber DESC
结果:
+------------+------+-----------+--------------------------+---------------+---------+
| Date | Flag | RowNumber | MaxPreviousNullRowNumber | RowNumberRest | Counter |
+------------+------+-----------+--------------------------+---------------+---------+
| 2019-09-01 | NULL | 20 | 19 | 1 | NULL |
| 2019-08-01 | NULL | 19 | 17 | 2 | NULL |
| 2019-07-01 | 1 | 18 | 17 | 1 | 1 |
| 2019-06-01 | NULL | 17 | 15 | 2 | NULL |
| 2019-05-01 | 1 | 16 | 15 | 1 | 1 |
| 2019-04-01 | NULL | 15 | 14 | 1 | NULL |
| 2019-03-01 | NULL | 14 | 13 | 1 | NULL |
| 2019-02-01 | NULL | 13 | 11 | 2 | NULL |
| 2019-01-01 | 1 | 12 | 11 | 1 | 1 |
| 2018-12-01 | NULL | 11 | 9 | 2 | NULL |
| 2018-11-01 | 1 | 10 | 9 | 1 | 1 |
| 2018-10-01 | NULL | 9 | 5 | 4 | NULL |
| 2018-09-01 | 1 | 8 | 5 | 3 | 3 |
| 2018-08-01 | 1 | 7 | 5 | 2 | 2 |
| 2018-07-01 | 1 | 6 | 5 | 1 | 1 |
| 2018-06-01 | NULL | 5 | 0 | 5 | NULL |
| 2018-05-01 | 1 | 4 | 0 | 4 | 4 |
| 2018-04-01 | 1 | 3 | 0 | 3 | 3 |
| 2018-03-01 | 1 | 2 | 0 | 2 | 2 |
| 2018-02-01 | 1 | 1 | 0 | 1 | 1 |
| 2018-01-01 | NULL | 0 | NULL | NULL | NULL |
+------------+------+-----------+--------------------------+---------------+---------+
答案 1 :(得分:0)