【问题标题】:Convert to number of rows based on record value根据记录值转换为行数
【发布时间】:2016-01-02 06:47:21
【问题描述】:

我有一个场景,我目前陷入困境

表 abc 有金额,从日期,到日期,季度数(从今天开始计算)

例子:

amount  fromdate    todate      numberofquarters

140    01/01/2011   06/01/2014   14

我必须按季度按比例制作上表 即 14 条记录为

amount  fromdate    todate      
10     01/01/2011   03/31/2011   
10     01/04/2011   06/30/2011   
10     01/07/2011   09/31/2011   
10     01/10/2011   12/31/2011  
10     01/01/2012   03/31/2012   
10     01/04/2012   06/30/2012   
10     01/07/2012   09/31/2012   
10     01/10/2012   12/31/2012  
10     01/01/2013   03/31/2013   
...and so on

请给我建议任何可以在不使用游标的情况下实现结果的方法。

【问题讨论】:

  • 我们能否对所需的输出有一点了解?我假设金额是总和,从日期是最小的开始日期,而今天是最大的日期。您希望多久运行一次此查询?另外,9/31 不是日期...
  • 金额是必须拆分为季度数的东西 在上面的示例中,从todate 和fromdate 计算了14 个季度。因此,金额应计算为金额/季度数。是的,这将按季度运行,但日期可以是任何值。

标签: sql-server tsql ssis


【解决方案1】:

您可以通过永久日期或数字表(每个日期或数字一行)来执行此类操作,也可以使用以下方式动态构建它:

;WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0)
    ,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) -- 4
    ,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv1 b) -- 16
    ,lv3 AS (SELECT 0 g FROM lv2 a CROSS JOIN lv2 b) -- 256
    ,Tally (n) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv3)
SELECT 
  abc.amount / numberofquarters, 
  dateadd(month, (n-1)*3, abc.fromdate) as fromdate,
  dateadd(day, -1, dateadd(month, n*3, abc.fromdate)) as todate
FROM 
  Tally T 
  join abc on abc.numberofquarters >= T.N
Order by fromdate

这将创建一个包含 256 行的表,如果您需要更多季度,则只需在 CTE 中添加一个类似的连接。然后将其与 abc 连接,以便使用该数字将月份添加到开始日期。

SQL Fiddle 中的示例

【讨论】:

  • 当我在 sql server 中运行它时,它说“已定义但未使用的公共表表达式”。我不明白为什么会出现这个问题?
  • @user2941762 检查您是否在 CTE 中的选择或最终选择中引用了 CTE (with) 部分中的所有虚拟表(lv0 .. lv3 和 Tally)。
  • 谢谢詹姆斯。我使用与上面完全相同的查询,但我使用的是#temp 表而不是 abc 表。临时表是否会导致此错误?
  • @user2941762 不,错误表明您没有引用 CTE。它适用于正常和温度。表格
【解决方案2】:

假设所需的输出为:
金额 = 金额列的总和,
fromdate = fomdate 列的最小值,
todate = todate 列的最小值 季度不跨越多年。

SELECT
    amount,
    fromdate,
    todate,
    COUNT(DISTINCT CASE 
       WHEN DATEPART(DAY, fromdate) > DATEPART(DAY, todate)
       THEN DATEDIFF(MONTH, fromdate, todate) - 1
       ELSE DATEDIFF(MONTH, fromdate, todate)
    END % 3 + YEAR(fromdate)) quarters
FROM (
    SELECT 
      SUM(amount) amount,
      MIN(fromdate) fromdate, 
      MAX(todate) todate
      FROM abc
 ) subq

应该会给你想要的结果

【讨论】:

  • 谢谢亲爱的。但这与我想要的完全相反。
猜你喜欢
  • 2021-10-30
  • 2022-11-25
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多