我有一个StatementsEntries表,如下所示
ID | Name | CaseId | StatementID | Amount | Balance | Paid
--------------------------------------------------------------------------
1 | Statement 1 | 1 | 1 | 1000 | 1000 | 1
--------------------------------------------------------------------------
2 | Payment | 1 | 0 | 1000 | 0 | 0
--------------------------------------------------------------------------
3 | Statement 2 | 3 | 2 | 500 | 500 | 0
--------------------------------------------------------------------------
4 | Statement 3 | 4 | 3 | 50 | 50 | 0
--------------------------------------------------------------------------
5 | Payment | 3 | 0 | 25 | 475 | 0
这是一个包含数百条记录的现有表格,基本上当有一个名称声明*和一个StatementId时,它意味着它被“开票”处理,那么对同一个案例ID的任何付款总是转到旧发票。在这种情况下,报表1已全额支付,因为该报表已生成,然后收到了余额金额的付款。
在声明2的情况下,它生成并且在声明3生成后收到付款,付款为25美元,因此付款适用于具有相同caseId的声明2,仅对特定情况ID付款被分配,所以如果我为CaseId 4付款,我会将其应用于对帐单3。
我想获得一个包含以下结果的查询:
StatementId | Name | Amount | Balance | IsPaid
----------------------------------------------------------
1 | Statement 1 | 1000 | 1000 | 1
---------------------------------------------------------
1 | Statement 1 | 1000 | 0 | 0
----------------------------------------------------------
2 | Statement 2 | 500 | 500 | 0
----------------------------------------------------------
2 | Statement 2 | 25 | 475 | 0
----------------------------------------------------------
3 | Statement 3 | 50 | 50 | 0
我已尝试使用UNION ALL,并加入同一个表但我正在努力为已付款的记录设置StatementId。会为此感到欣赏。
更新 我尝试了以下脚本
SELECT
[Statement ID] = CASE WHEN s.StatementId> 0 THEN s.StatementId ELSE x.StatementId END,
Name = CASE WHEN s.StatementId> 0 THEN s.Description ELSE x.Description END,
s.Amount,
s.Balance,
s.IsPaid
FROM StatementEntries s
OUTER APPLY(
SELECT *
FROM StatementEntries
WHERE
CaseId = s.CaseId
AND StatementId > s.StatementId AND StatementId > 0
ORDER BY ID
)x
WHERE s.CaseId = 1
ORDER BY s.ID
产生
StatementId | Name | Amount | Balance | IsPaid
----------------------------------------------------------
1 | Statement 1 | 1000 | 1000 | 1
---------------------------------------------------------
1 | Statement 1 | 1000 | 0 | 0
----------------------------------------------------------
2 | Statement 2 | 500 | 500 | 0
----------------------------------------------------------
1 | Statement 1 | 25 | 475 | 0
----------------------------------------------------------
3 | Statement 3 | 50 | 50 | 0
请参阅记录#4,它应该显示语句ID 2和语句2.我正在尝试使其工作,非常感谢你的答案,虽然我认为它让我走上了正确的道路。
更新2(添加架构和示例数据)
CREATE TABLE StatementsEntries (
Id INT,
Name VARCHAR(200),
Date DATE,
IsCredit BIT,
Amount DECIMAL,
CaseId INT,
IsAdjustment BIT,
StatementId INT,
Balance DECIMAL,
IsPaid BIT,
CreateDate DATE
)
INSERT INTO StatementsEntries VALUES
(1, 'Statement 4444','04/01/2007',0, 850,1,0,4444,850,1,'04/01/2007'),
(2, 'Payment made', '04/02/2007', 1, 850,1,0,0,0,0,'04/02/2007'),
(3, 'Statement 5555','08/01/2008', 0,1003, 1,0,5555,1003, 0,'08/01/2008'),
(4, 'Statement 7777','09/01/2008',0, 3000,2,0,7777,3000,0,'09/01/2008'),
(5, 'Statement 8883','10/01/2008', 0,1500, 5,0,8883,1500, 1,'10/01/2008'),
(6, 'Payment made', '10/02/2008', 1, 1500,5,0,0,0,0,'10/02/2008'),
(7, 'Statement 9992','11/01/2008',0, 1750,7,0,9992,1750,0,'11/01/2008'),
(8, 'Payment made', '04/02/2009', 1, 1002,1,0,0,648,0,'04/02/2009'),
(9, 'Statement 9994','08/01/2010', 0,1650, 1,0,9994,1650, 1,'08/01/2010'),
(10, 'Payment made', '09/02/2011', 1, 10,1,0,0,638,0,'09/02/2011');
答案 0 :(得分:2)
示例数据:
Id Name Date IsCredit Amount CaseId IsAdjustment StatementId Balance IsPaid CreateDate
----------- --------------- ---------- -------- ----------- ----------- ------------ ----------- ----------- ------ ----------
1 Statement 4444 2007-04-01 0 850 1 0 4444 850 1 2007-04-01
2 Payment made 2007-04-02 1 850 1 0 0 0 0 2007-04-02
3 Statement 5555 2008-08-01 0 1003 1 0 5555 1003 0 2008-08-01
4 Statement 7777 2008-09-01 0 3000 2 0 7777 3000 0 2008-09-01
5 Statement 8883 2008-10-01 0 1500 5 0 8883 1500 1 2008-10-01
6 Payment made 2008-10-02 1 1500 5 0 0 0 0 2008-10-02
7 Statement 9992 2008-11-01 0 1750 7 0 9992 1750 0 2008-11-01
8 Payment made 2009-04-02 1 1002 1 0 0 648 0 2009-04-02
9 Statement 9994 2010-08-01 0 1650 1 0 9994 1650 1 2010-08-01
10 Payment made 2011-09-02 1 10 1 0 0 638 0 2011-09-02
<强>解强>
SELECT
s.id,
[Statement ID] = CASE WHEN s.StatementID > 0 THEN s.StatementID ELSE x.StatementID END,
Name = CASE WHEN s.StatementID > 0 THEN s.Name ELSE x.Name END,
s.Amount,
s.Balance,
s.IsPaid
FROM StatementsEntries s
OUTER APPLY(
SELECT TOP 1 *
FROM StatementsEntries
WHERE
CaseID = s.CaseID
AND StatementID > 0
AND ID < s.Id
ORDER BY ID Desc
)x
ORDER BY [Statement ID], s.Id
<强> RESULT 强>
id Statement ID Name Amount Balance IsPaid
----------- ------------ --------------- ----------- ----------- ------
1 4444 Statement 4444 850 850 1
2 4444 Statement 4444 850 0 0
3 5555 Statement 5555 1003 1003 0
8 5555 Statement 5555 1002 648 0
4 7777 Statement 7777 3000 3000 0
5 8883 Statement 8883 1500 1500 1
6 8883 Statement 8883 1500 0 0
7 9992 Statement 9992 1750 1750 0
9 9994 Statement 9994 1650 1650 1
10 9994 Statement 9994 10 638 0
答案 1 :(得分:1)
使用Cross Apply
SELECT Dense_rank()OVER(ORDER BY cs.name) StatementID,
cs.name,
amount,
Balance,
paid
FROM Yourtable a
CROSS apply (SELECT TOP 1 name
FROM Yourtable b
WHERE a.CaseId = b.CaseId
ORDER BY id) cs
答案 2 :(得分:1)
试试这个:
select distinct src.caseid,
src.name,
max(src.statementid) over (partition by src.caseid order by src.id) statementid,
src.amount,
src.balance,
src.paid ispaid
from tbl src
left join tbl tgt on tgt.caseid = src.caseid and tgt.statementid = 0
order by caseid, src.balance desc
注意:这不适用于SQL Server 2005下的SQL Server版本。
答案 3 :(得分:0)
使用示例数据,以下查询:
SELECT S.Id, S.Name, S.Date, S.IsCredit, S.Amount, S.CaseId, S.IsAdjustment, S.StatementId, S.Balance, S.IsPaid, S.CreateDate
FROM
StatementsEntries S
WHERE
S.IsCredit = 0
UNION ALL
SELECT P.Id, S.Name, P.Date, P.IsCredit, P.Amount, P.CaseId, P.IsAdjustment, S.StatementId, P.Balance, P.IsPaid, P.CreateDate
FROM
StatementsEntries P
CROSS APPLY (
SELECT TOP (1) S.StatementId, S.Name
FROM StatementsEntries S
WHERE
S.CaseId = P.CaseId
AND S.IsCredit = 0
AND S.Id < P.Id
ORDER
BY S.Id DESC
) S
WHERE
IsCredit = 1
ORDER BY StatementId, Id
产生以下结果:
╔════╦════════════════╦════════════╦══════════╦════════╦════════╦══════════════╦═════════════╦═════════╦════════╦════════════╗
║ Id ║ Name ║ Date ║ IsCredit ║ Amount ║ CaseId ║ IsAdjustment ║ StatementId ║ Balance ║ IsPaid ║ CreateDate ║
╠════╬════════════════╬════════════╬══════════╬════════╬════════╬══════════════╬═════════════╬═════════╬════════╬════════════╣
║ 1 ║ Statement 4444 ║ 2007-04-01 ║ 0 ║ 850 ║ 1 ║ 0 ║ 4444 ║ 850 ║ 1 ║ 2007-04-01 ║
║ 2 ║ Statement 4444 ║ 2007-04-02 ║ 1 ║ 850 ║ 1 ║ 0 ║ 4444 ║ 0 ║ 0 ║ 2007-04-02 ║
║ 3 ║ Statement 5555 ║ 2008-08-01 ║ 0 ║ 1003 ║ 1 ║ 0 ║ 5555 ║ 1003 ║ 0 ║ 2008-08-01 ║
║ 8 ║ Statement 5555 ║ 2009-04-02 ║ 1 ║ 1002 ║ 1 ║ 0 ║ 5555 ║ 648 ║ 0 ║ 2009-04-02 ║
║ 4 ║ Statement 7777 ║ 2008-09-01 ║ 0 ║ 3000 ║ 2 ║ 0 ║ 7777 ║ 3000 ║ 0 ║ 2008-09-01 ║
║ 5 ║ Statement 8883 ║ 2008-10-01 ║ 0 ║ 1500 ║ 5 ║ 0 ║ 8883 ║ 1500 ║ 1 ║ 2008-10-01 ║
║ 6 ║ Statement 8883 ║ 2008-10-02 ║ 1 ║ 1500 ║ 5 ║ 0 ║ 8883 ║ 0 ║ 0 ║ 2008-10-02 ║
║ 7 ║ Statement 9992 ║ 2008-11-01 ║ 0 ║ 1750 ║ 7 ║ 0 ║ 9992 ║ 1750 ║ 0 ║ 2008-11-01 ║
║ 9 ║ Statement 9994 ║ 2010-08-01 ║ 0 ║ 1650 ║ 1 ║ 0 ║ 9994 ║ 1650 ║ 1 ║ 2010-08-01 ║
║ 10 ║ Statement 9994 ║ 2011-09-02 ║ 1 ║ 10 ║ 1 ║ 0 ║ 9994 ║ 638 ║ 0 ║ 2011-09-02 ║
╚════╩════════════════╩════════════╩══════════╩════════╩════════╩══════════════╩═════════════╩═════════╩════════╩════════════╝
答案 4 :(得分:0)
这应该可以解决问题
SELECT id,
ISNULL([Statement].StatementId, SE.StatementId) AS StatementId
, ISNULL([Statement].Name, SE.Name) AS Name
, Date
, IsCredit
, Amount
, CaseId
, IsAdjustment
, Balance
, IsPaid
, CreateDate
FROM StatementsEntries AS SE
OUTER APPLY(
SELECT Name, StatementId
FROM StatementsEntries AS SE_name
WHERE SE_name.Id = SE.CaseId
AND SE.IsCredit = 1
) AS [Statement]
ORDER BY StatementId