根据记录值转换为行数
Convert to number of rows based on record value
我有一个场景,我目前被困在
table abc having amount,fromdate,todate,numberofquarters(从todate fromdate计算)
示例:
amount fromdate todate numberofquarters
140 01/01/2011 06/01/2014 14
我必须按季度按比例完成上述 table
即 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
请建议我可以在不使用游标的情况下实现结果的任何方法。
你可以通过永久日期或数字 table(每个日期或数字一行)来做这样的事情,或者动态地构造它,像这样:
;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 行的 table,如果您需要更多季度,则只需在 CTE 中再添加一个类似的联接。然后将其与 abc 结合,以便该数字用于将月份添加到开始日期。
中的示例
假设期望输出:
金额 = 金额列的总和,
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
应该会给你想要的结果
我有一个场景,我目前被困在
table abc having amount,fromdate,todate,numberofquarters(从todate fromdate计算)
示例:
amount fromdate todate numberofquarters
140 01/01/2011 06/01/2014 14
我必须按季度按比例完成上述 table 即 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
请建议我可以在不使用游标的情况下实现结果的任何方法。
你可以通过永久日期或数字 table(每个日期或数字一行)来做这样的事情,或者动态地构造它,像这样:
;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 行的 table,如果您需要更多季度,则只需在 CTE 中再添加一个类似的联接。然后将其与 abc 结合,以便该数字用于将月份添加到开始日期。
中的示例假设期望输出:
金额 = 金额列的总和,
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
应该会给你想要的结果