我在SQL中有一个这样的表:

assetId price volume netVolume date transactionDateTime
1 200.00 100 100 2023-05-12 2023-05-12 10:32:10.000
1 200.00 100 200 2023-05-12 2023-05-12 10:50:10.000
3 300.00 100 100 2023-05-15 2023-05-15 11:40:46.000
2 200.00 100 500 2023-05-15 2023-05-15 12:18:01.000
3 300.00 100 100 2023-05-16 2023-05-16 11:50:31.000
2 200.00 100 600 2023-05-16 2023-05-16 12:20:18.000

正如您在某些天看到的,我们可能有多行具有相同的assets资源 ID(2023-05-12),或者我们可能没有任何东西. 我要创建一个CTE以获取具有以下规则的新表:

  1. 从@startDate开始,每天转到@endDate
  2. 如果有多行相同的assets资源 ID,只需 Select 最后一行(基于TransactionDateTime)
  3. 如果对于特定日期没有assets资源 ID的行,则添加最后一个现有的行,但将日期更改为当前日期,所有其他数据必须保持未链接状态.如果找不到任何以前的数据,请不要添加行. 我设法使用下面的CTE完成了第一部分,但我找不到一种方法来完成第二部分:
with CTE AS (
        SELECT assetId, rowNumber, price, volume, netVolume, date, transactionDateTime,
        ROW_NUMBER()OVER(PARTITION BY td.assetId,td.date order by td.transactionDateTime desc) AS RN
        FROM transactiondData td
)
    SELECT assetId, rowNumber, price, volume, netVolume, date, transactionDateTime
    FROM CTE
    WHERE RN = 1 AND date >= @startDate AND date <= @endDate
    ORDER BY transactionDateTime;

最后,我必须有一个这样的表,想想@startDate=2023-05-13和@endDate=2023-05-17:

assetId price volume netVolume date transactionDateTime
1 200.00 100 200 2023-05-13 2023-05-15 10:50:10.000
1 200.00 100 200 2023-05-14 2023-05-15 10:50:10.000
1 200.00 100 200 2023-05-15 2023-05-15 10:50:10.000
3 300.00 100 100 2023-05-15 2023-05-15 11:40:46.000
2 200.00 100 500 2023-05-15 2023-05-15 12:18:01.000
3 300.00 100 100 2023-05-16 2023-05-16 11:50:31.000
1 200.00 100 200 2023-05-16 2023-05-15 10:50:10.000
2 200.00 100 600 2023-05-16 2023-05-16 12:20:18.000
3 300.00 100 100 2023-05-17 2023-05-16 11:50:31.000
1 200.00 100 200 2023-05-17 2023-05-15 10:50:10.000
2 200.00 100 600 2023-05-17 2023-05-16 12:20:18.000

我怎么能这样做呢?

推荐答案

我们可以使用递归查询来生成日期范围,然后将其与assets资源 列表一起使用cross join:这为我们提供了可能的组合.然后,产生对应事务的简单方法是applytop:

with dates as (
    select @startDate dt
    union all select dateadd(day, 1, dt) from dates where dt < @endDate
)
select t.assetId, t.price, t.volume, t.netVolume, d.dt as date, t.transactionDateTime
from dates d
cross join (select distinct assetId from transactiondData) a
cross apply (
    select top (1) t.*
    from transactiondData t
    where t.date <= d.dt and t.assetId = a.assetId
    order by t.transactionDateTime desc
) t
order by d.dt, t.transactionDateTime

注意:由于我们使用cross apply,因此将跳过没有前面事务的"缺失"行,因为子查询不返回任何行.

100:

assetId price volume netVolume date transactionDateTime
1 200.00 100 200 2023-05-13 2023-05-12 10:50:10.000
1 200.00 100 200 2023-05-14 2023-05-12 10:50:10.000
1 200.00 100 200 2023-05-15 2023-05-12 10:50:10.000
3 300.00 100 100 2023-05-15 2023-05-15 11:40:46.000
2 200.00 100 500 2023-05-15 2023-05-15 12:18:01.000
1 200.00 100 200 2023-05-16 2023-05-12 10:50:10.000
3 300.00 100 100 2023-05-16 2023-05-16 11:50:31.000
2 200.00 100 600 2023-05-16 2023-05-16 12:20:18.000
1 200.00 100 200 2023-05-17 2023-05-12 10:50:10.000
3 300.00 100 100 2023-05-17 2023-05-16 11:50:31.000
2 200.00 100 600 2023-05-17 2023-05-16 12:20:18.000

Sql相关问答推荐

在postgresql中使用来自另一个字段的日期名称作为JSONB查询中的关键字

GROUP BY和GROUP_CONCAT用于计算比赛排名

在甲骨文中查找前一个星期一的S日期

为表中每个缺少的引用创建新行

Oracle SQL根据列中的条件 Select 最大记录数

如何查询jsonb列是一个对象数组?

同一表的Oracle SQL更新(含YTD合计)

在子窗口SQL Presto中使用特定条件执行值计数

如何在多列上编写具有不同条件的查询?

统计PostgreSQL中前10个最大大小表的行数

group-by-clause具有特定列,而不是oracle的toad中的all

将SQL Server查询改进为;线程安全;

Grafana SQL 模板变量(值、文本)

特殊条件计算小计

JSON对象查询SQL服务器

如何使用SQL将患者平均分配给他们所在地区的doctor

基于字符串的SQL查询

COBOL\DB2作业(job)需要帮助?快来获取专业指导!

使用 regexp_replace 替换所有出现的特殊字符

snowflake插入覆盖行为