下面我提供了一个代码,该代码在一定程度上完成了这个有趣的任务,但是由于我的SQL知识限制,该代码可能设计不佳。主要问题是,查询在执行时会给出 random (更确切地说是3种不同)的结果。我的猜测是,嵌套查询中的行按“随机”选择的列进行排序,这就是为什么最终结果不同(平衡点取决于顺序)的原因。
内部带有SELECT
的{{1}}创建一个r日期列表和两个累积和,例如:
GROUP
尝试在附件中添加示例数据(由于注释下方而删除)。
在第二个嵌套的rIndex r TotalPerDay CumulativeSum1 CumulativeSum2
1 02.05.2019 92,81 92,81 0
2 03.05.2019 24,81 117,61 0
3 06.05.2019 43,79 161,40 60
4 07.05.2019 78,65 240,05 120
5 09.05.2019 33,99 274,04 180
6 10.05.2019 73,22 347,26 240
7 13.05.2019 19,24 366,50 300
8 14.05.2019 150,77 517,27 360
9 15.05.2019 22,69 539,95 420
10 16.05.2019 4,96 544,91 480
11 17.05.2019 17,45 562,36 540
12 20.05.2019 27,19 589,55 600
13 21.05.2019 12,45 602,00 660
14 22.05.2019 18,08 620,08 720
15 23.05.2019 3,49 623,57 780
16 24.05.2019 10,51 634,09 840
17 27.05.2019 6,19 640,28 900
18 28.05.2019 3,01 643,29 960
19 29.05.2019 2,68 645,97 1020
20 30.05.2019 184,51 830,48 1080
中,找到一个平衡点,这是一个(第一个)日期,其中SELECT
。然后,我必须找到带有总和的天数索引(因为也有没有数据的天数),这就是最终结果;它是以下查询中最高的CumulativeSum1 > CumulativeSum2
:
SELECT
我谦虚地为明显的问题征求建议:
此外,我刚刚意识到最顶层的查询中存在差异,我在整个银行工作日中获取索引,但是索引应该在非空的银行工作日中得到...
一些示例数据:
DECLARE @eDate as Date
DECLARE @DayLimit INT
SET @DayLimit = 60 -- let's assume a constant here
SET @eDate = DATEFROMPARTS('2019','05','31')
-- get balance point INDEX over non-empty days
SELECT (SELECT COUNT(cDate) FROM Calendar WHERE KindOfDay = 'BANKDAY' AND cDate BETWEEN GETDATE() AND SRC3.BalanceDate) as rIndex
FROM
(
SELECT TOP 1 SRC2.rDate -- get first balance point (date)
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY SRC.rDate) as RowNo
,SRC.rDate
,SRC.TotalPerDay -- not required for processing, included just for info and check
,(SELECT (SUM((eTime-ISNULL(rDura,0))/60)) FROM MyTable1 as MT WHERE MT.r <= SRC.rDate AND MT.r < @eDate) as CumulativeSum1
,((SELECT COUNT(cDate) FROM Calendar WHERE KindOfDay = 'BANKDAY' AND cDate BETWEEN GETDATE() AND SRC.rDate) * @DayLimit) as CumulativeSum2
FROM (
SELECT
CASE
WHEN CAST(r as DATE) < CAST(GETDATE() as date)
THEN DATEADD(dd,-1,CAST(GETDATE() as date))
ELSE CAST(r as date)
END as rDate,
SUM((eTime-ISNULL(rDura,0))/60) as TotalPerDay
FROM MyTable1
WHERE r < @eDate
GROUP BY -- group by non-empty dates, group all past dates to yesterday
CASE
WHEN CAST(r as DATE) < CAST(GETDATE() as date)
THEN DATEADD(dd,-1,CAST(GETDATE() as date))
ELSE CAST(r as date)
END
) as SRC
--ORDER BY rDate
) as SRC2 -- compiled list of sums per day
WHERE SRC2.CumulativeSum2 > SRC2.CumulativeSum1; -- balance condition
) as SRC3
答案 0 :(得分:0)
建议ROW_NUMBER()
本身并不能帮助克服问题。我必须将任务分为两个步骤:拳头,我必须设置一个变量@bDate
来存储2个内部嵌套的SELECT
的结果,然后在单独的{{1 }}步骤。
SELECT