我正在尝试建立一个SQL查询,该查询将为我提供具有相同价格的日期的日期范围。如果价格出现突破,我希望能在新的行中看到它。即使一个月中的某个时间有相同的价格,但如果价格介于两者之间的某个时间有变化,我希望将其视为具有特定日期范围的两个单独的行。
样本数据:
Date Price 1-Jan 3.2 2-Jan 3.2 3-Jan 3.2 4-Jan 3.2 5-Jan 3.2 6-Jan 3.2 7-Jan 3.2 8-Jan 3.2 9-Jan 3.5 10-Jan 3.5 11-Jan 3.5 12-Jan 3.5 13-Jan 3.5 14-Jan 4.2 15-Jan 4.2 16-Jan 4.2 17-Jan 3.2 18-Jan 3.2 19-Jan 3.2 20-Jan 3.2 21-Jan 3.2 22-Jan 3 23-Jan 3 24-Jan 3 25-Jan 3 26-Jan 3 27-Jan 3 28-Jan 3 29-Jan 3.5 30-Jan 3.5 31-Jan 3.5
所需结果:
Price Date Range 3.2 1-8 3.5 9-13 4.2 14-16 3.2 17-22 3 22-28 3.5 29-31
我认为没有其他答案是正确的。
GROUP BY 不会工作
GROUP BY
使用会ROW_NUMBER()强制将数据放入物理的“记录归档系统”结构中,然后将其作为物理记录进行处理。以巨大的性能成本为代价。当然,为了写这样的代码,它迫使你 想 在RFS而不是关系思维的条款。
ROW_NUMBER()
使用CTE是相同的。遍历数据,尤其是不变的数据。费用略有不同。
游标绝对是错误的事情,原因有很多。(a)游标需要代码,并且您已请求一个视图(b)游标放弃了集处理引擎,并恢复为逐行处理。同样,不是必需的。如果我的任何团队中的开发人员都在关系数据库(即非记录归档系统)上使用了游标或临时表,我会射击它们。
您的 数据 是关系型的,逻辑的,两个给定的 数据 列就足够了。
当然,我们有以形成一视图(派生关系),以获得所需的报告,但由纯进行选择,这是处理(将其转换为一个完全不同的 文件 ,这是物理的,然后处理所述 文件 ;或者临时表;或工作表;或CTE;或ROW_Number();等)。
与有一个议程的“理论家”的哀叹相反,SQL可以很好地处理关系数据。而您的数据就是关系型的。
因此,请保持“关系”心态,数据的“关系”视图和集合处理心态。可以使用单个SELECT来满足关系数据库上的每个报告要求。无需退回1970年以前的ISAM文件处理方法。
我将假设主键(给出关系行唯一性的一组列)为Date,,根据给出的示例数据,数据类型为DATE.
Date,
DATE.
试试这个:
CREATE VIEW MyTable_Base_V -- Foundation View AS SELECT Date, Date_Next, Price FROM ( -- Derived Table: project rows with what we need SELECT Date, [Date_Next] = DATEADD( DD, 1, O.Date ), Price, [Price_Next] = ( SELECT Price -- NULL if not exists FROM MyTable WHERE Date = DATEADD( DD, 1, O.Date ) ) FROM MyTable MT ) AS X WHERE Price != Price_Next -- exclude unchanging rows GO CREATE VIEW MyTable_V -- Requested View AS SELECT [Date_From] = ( -- Date of the previous row SELECT MAX( Date_Next ) -- previous row FROM MyTable_V WHERE Date_Next < MT.Date ), [Date_To] = Date, -- this row Price FROM MyTable_Base_V MT GO SELECT * FROM MyTable_V GO
当然,这是一种方法,因此它是通用的,它可以被用来确定From_与To_任何数据范围(在此,a的Date范围)的基础上的任何数据变化(在这里,在一变化Price)。
From_
To_
Date
Price
在这里,您Dates是连续的,因此确定Date_Next很简单:将递增Date1天。如果PK在增加但 不 连续(例如DateTime或TimeStamp或其他某个键),则将派生表更改X为:
Dates
Date_Next
DateTime
TimeStamp
X
-- Derived Table: project rows with what we need SELECT DateTime, [DateTime_Next] = ( -- first row > this row SELECT TOP 1 DateTime -- NULL if not exists FROM MyTable WHERE DateTime > MT.DateTime ), Price, [Price_Next] = ( -- first row > this row SELECT TOP 1 Price -- NULL if not exists FROM MyTable WHERE DateTime > MT.DateTime ) FROM MyTable MT
请随时发表评论,提出问题等。