我正在寻找帮助来创建查询,以解决以下问题:
让我们想象一下这行:
Name StartDate EndDate Paid James 10-10-2010 17-02-2011 860
并且按照要求继承了表的架构:
payment_details (name VARCHAR(50) NOT NULL,
start_date DATETIME NOT NULL,
end_date DATETIME NOT NULL,
paidFLOAT NOT NULL)
现在我需要一种方法来分割这一行,所以我可以看到他每个月支付的费用,对于他的期间,一个返回的查询:
Name Year Month Paid James 2010 10 172 James 2010 11 172 James 2010 12 172 James 2011 01 172 James 2011 02 172
有许多不同的客户使用不同的StartDate / EndDate和支付金额,因此查询必须处理此问题。如何在SQL(MS SQL Server 2005)中执行此操作?
非常感谢帮助!
答案 0 :(得分:3)
你需要:
你当然可能需要调整它......
--DROP TABLE #numbers
--DROP TABLE #payment_details
CREATE TABLE #numbers (num smallint PRIMARY KEY)
CREATE TABLE #payment_details (name VARCHAR(50) NOT NULL,
start_date DATETIME NOT NULL,
end_date DATETIME NOT NULL,
paid FLOAT NOT NULL)
INSERT #payment_details VALUES ('James', '20101010', '20110217', 860)
INSERT #payment_details VALUES ('Jane', '20101110', '20110117', 900)
INSERT #payment_details VALUES ('John', '20101128', '20101128', 500)
INSERT #numbers
SELECT TOP 1000
ROW_NUMBER() OVER (ORDER BY c1.object_id) -1
FROM
sys.columns c1 CROSS JOIN sys.columns c2
SELECT
P.name,
DATEPART(year, DATEADD(month, N.Num, start_date)),
DATEPART(month, DATEADD(month, N.Num, start_date)),
P.paid / (DATEDIFF(month, start_date, end_date) + 1)
FROM
#payment_details P
JOIN
#numbers N ON DATEDIFF(month, start_date, end_date) >= N.num
答案 1 :(得分:1)
您可能需要日期表,包含合理期间的每个日期。然后,您可以将其加入付款,计算付款金额作为总金额除以月份的期间长度。
select p.name, d.year, d.month, p.paid/(datediff(m, p.startdate, p.enddate) + 1)
from (
select year(date) as year, month(date) as month, min(date) as monthbegin, max(date) as monthend
from datestable
group by year(date), month(date)
) d
left join payment_detail p on d.monthbegin<p.enddate and d.monthend>p.startdate
我希望我的加入条件合适,随意纠正(我没有可能在这里测试)。
答案 2 :(得分:0)
关于我在直接SQL中看到这样做的唯一方法是使用另一个名为Periods的表,其中包含所有年份和月份,如下所示:
Year Month
2010 10
2010 11
2010 12
2011 1
2011 2
2011 3
2011 4
依旧......
现在,您可以将付款明细表与该表一起加入:
SELECT PD.[name], Per.Year, Per.Month,
PD.payed / DateDiff(mm, PD.start_date, PD.end_date) AS Payed
FROM payment_details PD
INNER JOIN Periods Per On
Per.Year >= DatePart(yy, start_date) AND Per.Month >= DatePart(mm, start_date)
AND Per.Year <= DatePart(yy, end_date) AND Per.Month <= DatePart(mm, end_date)
ORDER BY PD.[name], Per.Year, Per.Month
否则,您可能需要创建一个存储过程并逐步完成这些月份并动态创建结果数据集。
答案 3 :(得分:0)
只是为了提供一些横向思考,你每个月需要一行吗?根据您是否,例如,从中计算某些内容,或者您要为某人审核创建报告,您可能不需要创建6行,其中唯一不同的数据是月/年。这也假设付款在几个月内均匀分配。通过选择姓名,开始年份,开始月份,结束年份,结束月份,然后将支付的总额除以((年差* 12)+月差异)来确定每月付款,可以很容易地写出来。
根据用途的不同,沿着这些线条的东西可能看起来更干净,而且有人打算将它打印出来的纸张少得多。 :)