使用'中的上一行值;对于XML路径';在MS SQL中
我有以下表格:使用'中的上一行值;对于XML路径';在MS SQL中,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有以下表格: TABLE A (CUSTOMER_LOAN): ============================= CUSTOMER_ID TOTAL_LOAN_AMOUNT XXX 100,000.00 YYY 200,000.00 TABLE B (SCHEDULE): ========================================= CUSTOMER_ID SCHEDULE_DATE SCHEDULE_AMOUNT XXX
TABLE A (CUSTOMER_LOAN):
=============================
CUSTOMER_ID TOTAL_LOAN_AMOUNT
XXX 100,000.00
YYY 200,000.00
TABLE B (SCHEDULE):
=========================================
CUSTOMER_ID SCHEDULE_DATE SCHEDULE_AMOUNT
XXX 20170102 30,000
XXX 20170302 10,000
XXX 20170602 15,000
YYY 20170203 50,000
YYY 20170403 100,000
YYY 20170703 30,000
我需要的是获得以下输出:
EXPECTED REPORT OUTPUT :
=============================
CUSTOMER_ID SCHEDULE_DATES SCHEDULE_PRINCIPAL
XXX 20170102/20170302/20170602 70,000/60,000/45,000
YYY 20170203/20170403/20170703 150,000/50,000/20,000
附表_本金按(未偿本金-附表_金额)计算。
i、 e.对于客户XXX,(70000=100000-30000)/(60000=70000-10000)/(45000=60000-15000)
以下是我的疑问:
SELECT A.CUSTOMER_ID
, STUFF((SELECT '/' + SCHEDULE_DATE FROM SCHEDULE B
WHERE B.CUSTOMER_ID = A.CUSTOMER_ID
FOR XML PATH('')), 1, 1, '') AS SCHEDULE_DATES
, STUFF((SELECT '/' + (A.TOTAL_LOAN_AMOUNT - CAST(B.SCHEDULE_AMOUNT AS MONEY)) FROM SCHEDULE B
WHERE B.CUSTOMER_ID = A.CUSTOMER_ID
FOR XML PATH('')), 1, 1, '') AS SCHEDULE_PRINCIPAL
FROM CUSTOMER_LOAN A
正如您所看到的,明细表本金是错误的,因为总贷款金额是恒定的,并且计算(A.TOTAL\u LOAN\u AMOUNT-CAST(B.SCHEDULE\u AMOUNT As MONEY))未累积到下一行
有什么方法可以像预期的报告那样输出结果呢?我正在使用SQL Server 2012。任何帮助都将不胜感激。尝试以下方法(我用SUM(B.计划金额)替换计划金额)(按计划日期订购):
正如另外两个答案所详细说明的,中心思想是
SUM()。(在原始问题中,CUSTOMER\u LOAN
和SCHEDULE
已作为表格存在,可以从CTE中删除。)
这应该是您想要的。关键位是前面的无边界行,这是运行总数
CREATE TABLE #CUSTOMER_LOAN (CUSTOMER_ID INT, TOTAL_LOAN_AMOUNT
DECIMAL(38,2));
CREATE TABLE #SCHEDULE (CUSTOMER_ID INT, SCHEDULE_DATE VARCHAR(8), SCHEDULE_AMOUNT DECIMAL(38,2));
INSERT INTO #CUSTOMER_LOAN ( CUSTOMER_ID, TOTAL_LOAN_AMOUNT ) VALUES (1, 100000.00);
INSERT INTO #CUSTOMER_LOAN ( CUSTOMER_ID, TOTAL_LOAN_AMOUNT ) VALUES (2, 200000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (1,'20170102',30000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (1,'20170202',10000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (1,'20170602',15000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (2,'20170203',50000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (2,'20170403',100000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (2,'20170703',30000.00);
; WITH CTE AS
(
SELECT A.CUSTOMER_ID,
B.SCHEDULE_DATE,
a.TOTAL_LOAN_AMOUNT
- SUM(B.SCHEDULE_AMOUNT) OVER (PARTITION BY A.CUSTOMER_ID
ORDER BY B.SCHEDULE_DATE
ROWS UNBOUNDED PRECEDING) AS SCHEDULE_PRINCIPAL
FROM #CUSTOMER_LOAN A
INNER JOIN #SCHEDULE B ON A.CUSTOMER_ID = B.CUSTOMER_ID
)
SELECT CUSTOMER_ID,
LEFT(MAX(SCHEDULE_DATES), LEN(MAX(SCHEDULE_DATES))-1),
LEFT(MAX(SCHEDULE_PRINCIPALS), LEN(MAX(SCHEDULE_PRINCIPALS))-1)
FROM CTE
CROSS APPLY
(
SELECT CTE2.SCHEDULE_DATE + '/'
FROM CTE CTE2
WHERE CTE.CUSTOMER_ID = CTE2.CUSTOMER_ID
ORDER BY CTE2.SCHEDULE_DATE
FOR XML PATH('')
) D (SCHEDULE_DATES)
CROSS APPLY
(
SELECT CONVERT(VARCHAR, CTE2.SCHEDULE_PRINCIPAL) + '/'
FROM CTE CTE2
WHERE CTE.CUSTOMER_ID = CTE2.CUSTOMER_ID
ORDER BY CTE.SCHEDULE_DATE
FOR XML PATH('')
) P (SCHEDULE_PRINCIPALS)
GROUP BY CTE.CUSTOMER_ID
抱歉,我已更新查询。B.SCHEDULE_金额应转换为货币。然后我使用您的查询,系统返回以下错误:范围窗口框架的按列表排序不能包含LOB类型的表达式。我更新了查询,但您不应将日期存储在varchar(max)列中。请勿使用转换(varchar,…)
。这相当于这里的CONVERT(VARCHAR(30),…)
,但这一点并不明显。(具体地说,它的长度“无论如何都不能满足输入参数的长度”。)使用不带长度的VARCHAR
是一个错误。
with
Principals as
(
select b.*,TOTAL_LOAN_AMOUNT-SUM(SCHEDULE_AMOUNT) over (partition by b.CUSTOMER_ID order by SCHEDULE_DATE) principal from CUSTOMER_LOAN a
inner join SCHEDULE b
on a.CUSTOMER_ID=b.CUSTOMER_ID
)
select
CUSTOMER_ID
,(
STUFF((SELECT '/' + SCHEDULE_DATE FROM SCHEDULE B
WHERE B.CUSTOMER_ID = A.CUSTOMER_ID
FOR XML PATH('')), 1, 1, '')
) Schedule_Dates
,STUFF((SELECT '/' + (convert(varchar(255),cast(b.principal as money),1)) FROM Principals B
WHERE B.CUSTOMER_ID = A.CUSTOMER_ID
FOR XML PATH('')), 1, 1, '') AS SCHEDULE_PRINCIPAL
from CUSTOMER_LOAN a
WITH CUSTOMER_LOAN AS (
SELECT * FROM (VALUES
('XXX', $100000),
('YYY', $200000)
) AS CUSTOMER_LOAN(CUSTOMER_ID, TOTAL_LOAN_AMOUNT)
), SCHEDULE AS (
SELECT * FROM (VALUES
('XXX', '20170102', $30000),
('XXX', '20170302', $10000),
('XXX', '20170602', $15000),
('YYY', '20170203', $50000),
('YYY', '20170403', $100000),
('YYY', '20170703', $30000)
) AS SCHEDULE(CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT)
), PRINCIPALS AS (
SELECT
S.CUSTOMER_ID,
S.SCHEDULE_DATE,
L.TOTAL_LOAN_AMOUNT - SUM(S.SCHEDULE_AMOUNT) OVER (
PARTITION BY S.CUSTOMER_ID
ORDER BY S.SCHEDULE_DATE
) AS SCHEDULE_PRINCIPAL
FROM SCHEDULE S
JOIN CUSTOMER_LOAN L ON S.CUSTOMER_ID = L.CUSTOMER_ID
)
SELECT CUSTOMER_ID, T.*
FROM CUSTOMER_LOAN CROSS APPLY (
SELECT STUFF((
SELECT CONCAT('/', P.SCHEDULE_DATE)
FROM PRINCIPALS P
WHERE P.CUSTOMER_ID = CUSTOMER_LOAN.CUSTOMER_ID
ORDER BY P.SCHEDULE_DATE
FOR XML PATH('')
), 1, 1, ''),
STUFF((
SELECT CONCAT('/', P.SCHEDULE_PRINCIPAL)
FROM PRINCIPALS P
WHERE P.CUSTOMER_ID = CUSTOMER_LOAN.CUSTOMER_ID
ORDER BY P.SCHEDULE_DATE
FOR XML PATH('')
), 1, 1, '')
) T(SCHEDULE_DATES, SCHEDULE_PRINCIPAL)
CREATE TABLE #CUSTOMER_LOAN (CUSTOMER_ID INT, TOTAL_LOAN_AMOUNT
DECIMAL(38,2));
CREATE TABLE #SCHEDULE (CUSTOMER_ID INT, SCHEDULE_DATE VARCHAR(8), SCHEDULE_AMOUNT DECIMAL(38,2));
INSERT INTO #CUSTOMER_LOAN ( CUSTOMER_ID, TOTAL_LOAN_AMOUNT ) VALUES (1, 100000.00);
INSERT INTO #CUSTOMER_LOAN ( CUSTOMER_ID, TOTAL_LOAN_AMOUNT ) VALUES (2, 200000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (1,'20170102',30000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (1,'20170202',10000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (1,'20170602',15000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (2,'20170203',50000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (2,'20170403',100000.00);
INSERT INTO #SCHEDULE ( CUSTOMER_ID, SCHEDULE_DATE, SCHEDULE_AMOUNT) VALUES (2,'20170703',30000.00);
; WITH CTE AS
(
SELECT A.CUSTOMER_ID,
B.SCHEDULE_DATE,
a.TOTAL_LOAN_AMOUNT
- SUM(B.SCHEDULE_AMOUNT) OVER (PARTITION BY A.CUSTOMER_ID
ORDER BY B.SCHEDULE_DATE
ROWS UNBOUNDED PRECEDING) AS SCHEDULE_PRINCIPAL
FROM #CUSTOMER_LOAN A
INNER JOIN #SCHEDULE B ON A.CUSTOMER_ID = B.CUSTOMER_ID
)
SELECT CUSTOMER_ID,
LEFT(MAX(SCHEDULE_DATES), LEN(MAX(SCHEDULE_DATES))-1),
LEFT(MAX(SCHEDULE_PRINCIPALS), LEN(MAX(SCHEDULE_PRINCIPALS))-1)
FROM CTE
CROSS APPLY
(
SELECT CTE2.SCHEDULE_DATE + '/'
FROM CTE CTE2
WHERE CTE.CUSTOMER_ID = CTE2.CUSTOMER_ID
ORDER BY CTE2.SCHEDULE_DATE
FOR XML PATH('')
) D (SCHEDULE_DATES)
CROSS APPLY
(
SELECT CONVERT(VARCHAR, CTE2.SCHEDULE_PRINCIPAL) + '/'
FROM CTE CTE2
WHERE CTE.CUSTOMER_ID = CTE2.CUSTOMER_ID
ORDER BY CTE.SCHEDULE_DATE
FOR XML PATH('')
) P (SCHEDULE_PRINCIPALS)
GROUP BY CTE.CUSTOMER_ID