【问题标题】:tsql analytic querytsql解析查询
【发布时间】:2023-04-07 07:47:02
【问题描述】:

我有事实和日期维度表。我需要编写一个查询,为每个日期成员返回其聚合函数(sum(amount))。但是这个聚合函数需要根据日期进行过滤。

FACT table: InvFactMain
Dim table: Dates

目前我有这个查询:

SELECT D.DATE
       ,(
        SELECT sum(inline.InventoryRetailAmount)
        FROM InvFactMain inline
        WHERE inline.DocumentDate >= DATEADD(day, - @x, D.DATE)
            AND inline.DocumentDate < dateadd(day, - @y, D.DATE)
        ) AS [RetailAmount]
FROM InvFactMain F
     JOIN Dates D ON D.Date_ID = F.DateId
GROUP BY D.DATE

我确信有更好、更有效的方法来实现它。

• 我使用的是 SQL 2012,所以我可以使用分析函数如 LAG、LEAD 等。

有什么想法吗?

【问题讨论】:

  • 请您提供更多详细信息,但此聚合函数需要根据返回日期进行过滤

标签: sql sql-server performance tsql


【解决方案1】:

如果我理解这必须正确执行,我认为这应该是正确的......

SELECT D.Date, q.s AS [Sum]
FROM Dates D
CROSS APPLY (
    SELECT SUM(F.InventoryRetailAmount) s
    FROM InvFactMain F
    WHERE F.Date_ID = D.DateID
          AND D.Date BETWEEN DATEADD(day, -@x, D.Date) AND DATEADD(day, -@y, D.Date)
) q

【讨论】:

    【解决方案2】:

    这对你有帮助吗?

    SELECT  D.Date ,
            SUM(inline.InventoryRetailAmount) AS amount
    FROM    InvFactMain F
            INNER JOIN Dates D ON D.Date_ID = F.DateId
            INNER JOIN InvFactMain inv ON inv.DocumentDate >= DATEADD(DAY, -@x,
                                                                  D.Date)
                                          AND inv.DocumentDate < DATEADD(DAY, -@y,
                                                                  D.Date)
    GROUP BY D.Date
    HAVING  SUM(inline.InventoryRetailAmount) = YOUR_FILTER
    

    【讨论】:

      【解决方案3】:

      我相信您可以通过使用窗口函数来实现您的目标。我以冒险作品为例。

      SELECT       d.FullDateAlternateKey
                 ,f.SalesAmount
                 ,TotalSales = sum(SalesAmount) OVER (PARTITION BY d.FullDateAlternateKey ORDER BY d.FullDateAlternateKey            )
                 ,RunningTotalPerDay = sum(SalesAmount) OVER (PARTITION BY d.FullDateAlternateKey ORDER BY d.FullDateAlternateKey ROWS UNBOUNDED PRECEDING)
                 ,RunningTotalLastTenDays = sum(SalesAmount) OVER (ORDER BY d.FullDateAlternateKey ROWS BETWEEN 9 PRECEDING AND CURRENT ROW)
      FROM           [dbo].[DimDate] d
                 JOIN [dbo].[FactInternetSales] f 
                 ON d.DateKey = f.OrderDateKey
      

      查询的输出:

      +----------------------+-------------+------------+--------------------+-------------------------+
      | FullDateAlternateKey | SalesAmount | TotalSales | RunningTotalPerDay | RunningTotalLastTenDays |
      +----------------------+-------------+------------+--------------------+-------------------------+
      | 2005-07-01           | 3578.27     | 14477.3382 | 3578.27            | 3578.27                 |
      | 2005-07-01           | 3399.99     | 14477.3382 | 6978.26            | 6978.26                 |
      | 2005-07-01           | 3399.99     | 14477.3382 | 10378.25           | 6799.98                 |
      | 2005-07-01           | 699.0982    | 14477.3382 | 11077.3482         | 4099.0882               |
      | 2005-07-01           | 3399.99     | 14477.3382 | 14477.3382         | 4099.0882               |
      | 2005-07-02           | 3578.27     | 13931.52   | 3578.27            | 6978.26                 |
      | 2005-07-02           | 3578.27     | 13931.52   | 7156.54            | 7156.54                 |
      +----------------------+-------------+------------+--------------------+-------------------------+
      

      【讨论】:

        【解决方案4】:

        感谢您的回答。 我找到了一种非常简单的实现方法: (只是在连接谓词上添加了过滤器)

        select d.date_id,sum(f.InventoryRetailAmount) from InvFactMain f inner join dates d
        on f.DocumentDate >  dateadd(day,-@x,d.date)  and f.DocumentDate< dateadd(day,-@y,d.date)
        group by d.Date_ID
        order by d.Date_ID
        

        完美运行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-20
          • 1970-01-01
          • 2013-05-23
          • 2016-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多