我目前正在尝试在不包含此信息的表上建立父子关系。
就是一个金融账号列表和一个对应的类型,就是这样
虽然现在有一个逻辑,头账户将利润和损失账户分组,最后是总计。标题可以嵌套,总计也可以在此逻辑中形成父子结构是我当前的任务
我已经对应该导致父帐户切换的更改进行了排名。但是我有点坚持构建我的递归查询以一直移动到我想要的输出。
目前我在这个水平(简化示例)
WITH accounts AS (
SELECT
accountNumber, accountType
FROM (VALUES
(1000, 'heading'),
(1001, 'heading'),
(1010, 'profitAndLoss'),
(1020, 'profitAndLoss'),
(1021, 'profitAndLoss'),
(1025, 'profitAndLoss'),
(1099, 'totalFrom'),
(1300, 'heading'),
(1310, 'profitAndLoss'),
(1320, 'profitAndLoss'),
(1321, 'profitAndLoss'),
(1399, 'totalFrom'),
(2000, 'totalFrom'),
(2200, 'heading'),
(2210, 'profitAndLoss'),
(2211, 'profitAndLoss')
) AS t(accountNumber, accountType)
),
rankedAccounts AS (
SELECT
*,
COALESCE(
CASE WHEN LAG(accountNumber) OVER(ORDER BY accountNumber) IS NULL THEN 0 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('heading', 'headingStart') AND LAG(accountType, 2) OVER (ORDER BY accountNumber) IS NULL THEN 1 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('heading', 'headingStart') THEN 0 END,
CASE WHEN accountType IN ('profitAndLoss', 'status') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('heading', 'headingStart') THEN 1 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') AND LAG(accountType, 2) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') THEN 0 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') AND LAG(accountType, 2) OVER (ORDER BY accountNumber) IN ('profitAndLoss', 'status') THEN -1 END,
CASE WHEN accountType IN ('totalFrom', 'sumInterval') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') THEN -1 END,
0
) Rank
FROM
accounts
),
sumRank AS (
SELECT
accountNumber,
accountType,
SUM(Rank) OVER (ORDER BY rankedAccounts.accountNumber) sumRank
FROM rankedAccounts
)
SELECT
*
FROM
sumRank
此查询的结果数据如下
我想要的输出看起来像这样
我可以在 python 中使用一个非常简单的循环轻松完成此操作,但我无法在 T-SQL 中全神贯注
accountDictList = [
{'accountNumber': 1000, 'accountType':'heading', 'sumRank':0},
{'accountNumber': 1001, 'accountType':'heading', 'sumRank':1},
{'accountNumber': 1010, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1020, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1021, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1025, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1099, 'accountType':'totalFrom', 'sumRank':2},
{'accountNumber': 1300, 'accountType':'heading', 'sumRank':1},
{'accountNumber': 1310, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1320, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1321, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 1399, 'accountType':'totalFrom', 'sumRank':2},
{'accountNumber': 2000, 'accountType':'totalFrom', 'sumRank':1},
{'accountNumber': 2200, 'accountType':'heading', 'sumRank':1},
{'accountNumber': 2210, 'accountType':'profitAndLoss', 'sumRank':2},
{'accountNumber': 2211, 'accountType':'profitAndLoss', 'sumRank':2},
]
for i, account in enumerate(accountDictList):
try:
if i == 0:
parent = None
elif account['sumRank'] > accountDictList[i-1]['sumRank']:
grandparent = parent
parent = accountDictList[i-1]['accountNumber']
elif account['sumRank'] < accountDictList[i-1]['sumRank']:
parent = grandparent
except:
parent = parent
print(account, parent)
导致所需的输出
在 Python 中你有变量,在 sql 中没有,所以你需要子查询来获取想要的信息
WITH accounts AS (
SELECT
accountNumber, accountType
FROM (VALUES
(1000, 'heading'),
(1001, 'heading'),
(1010, 'profitAndLoss'),
(1020, 'profitAndLoss'),
(1021, 'profitAndLoss'),
(1025, 'profitAndLoss'),
(1099, 'totalFrom'),
(1300, 'heading'),
(1310, 'profitAndLoss'),
(1320, 'profitAndLoss'),
(1321, 'profitAndLoss'),
(1399, 'totalFrom'),
(2000, 'totalFrom'),
(2200, 'heading'),
(2210, 'profitAndLoss'),
(2211, 'profitAndLoss')
) AS t(accountNumber, accountType)
),
rankedAccounts AS (
SELECT
*,
COALESCE(
CASE WHEN LAG(accountNumber) OVER(ORDER BY accountNumber) IS NULL THEN 0 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('heading', 'headingStart') AND LAG(accountType, 2) OVER (ORDER BY accountNumber) IS NULL THEN 1 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('heading', 'headingStart') THEN 0 END,
CASE WHEN accountType IN ('profitAndLoss', 'status') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('heading', 'headingStart') THEN 1 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') AND LAG(accountType, 2) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') THEN 0 END,
CASE WHEN accountType IN ('heading', 'headingStart') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') AND LAG(accountType, 2) OVER (ORDER BY accountNumber) IN ('profitAndLoss', 'status') THEN -1 END,
CASE WHEN accountType IN ('totalFrom', 'sumInterval') AND LAG(accountType) OVER (ORDER BY accountNumber) IN ('totalFrom', 'sumInterval') THEN -1 END,
0
) Rank
FROM
accounts
),
sumRank AS (
SELECT
accountNumber,
accountType,
SUM(Rank) OVER (ORDER BY rankedAccounts.accountNumber) sumRank
FROM rankedAccounts
)
SELECT
*,
CASE WHEN sumrank = 0 then NULL
WHEN sumrank = 1 THEN ( SELECT accountNumber FROM sumRank WHERE sumRank = 0)
ELSE ( SELECT accountNumber FROM sumRank WHERE sumRank = 1 AND accountNumber < s1.accountNumber ORDER BY accountnumber DESC LIMIT 1)
END parent
FROM
sumRank s1
账号 | 账户类型 | 总排名 | 家长 |
---|---|---|---|
1000 | 标题 | 0 | 空 |
1001 | 标题 | 1 | 1000 |
1010 | 利润和损失 | 2 | 1001 |
1020 | 利润和损失 | 2 | 1001 |
1021 | 利润和损失 | 2 | 1001 |
1025 | 利润和损失 | 2 | 1001 |
1099 | 总计 | 2 | 1001 |
1300 | 标题 | 1 | 1000 |
1310 | 利润和损失 | 2 | 1300 |
1320 | 利润和损失 | 2 | 1300 |
1321 | 利润和损失 | 2 | 1300 |
1399 | 总计 | 2 | 1300 |
2000 | 总计 | 1 | 1000 |
2200 | 标题 | 1 | 1000 |
2210 | 利润和损失 | 2 | 2200 |
2211 | 利润和损失 | 2 | 2200 |