查询获取同一张表中1:N关系的数据
Posted
技术标签:
【中文标题】查询获取同一张表中1:N关系的数据【英文标题】:Query to fetch data with 1:N relationship in the same table 【发布时间】:2019-12-25 22:32:31 【问题描述】:使用的数据库:MS SQL Server
我有一个表,其中包含父会员帐户和子会员帐户在同一个表中的 1:N 关系(父帐户可以有任意数量的子帐户)。
我需要使用单个查询获取所有父帐户及其子帐户,并且由于我的应用程序(spring-batch 应用程序)一次处理每一行这些记录,因此我需要将所有子帐户连同父帐户在同一行。 (我可能对这里的方法有误。我是 Spring Batch 的新手)
我能够获得一位家长:一个孩子账户记录,但随后每个孩子账户都会重复父账户。
使用的数据库:MS SQL Server
我有一张会员资格表,其中包含所有订阅的会员资格。 成员资格可以有两种类型 - 父母和孩子。
Memberships 表 - 此表包含所有已发布的父级和子级成员资格:
Membership_Num|Membership_Type|Premium|Sub_Date|Pkg
MN001|Parent|1400.25|12-31-2013|BasePkg
MN002|Parent|1830.75|12-31-2008|BasePkg
MN003|Child|422.25|12-31-2014|BasePkg
MN004|Child|365.50|12-31-2015|PremiumPkg
MN005|Child|365.50|12-31-2015|PremiumPkg
MN006|Child|365.50|12-31-2015|PremiumPkg
MN007|Child|365.50|12-31-2015|PremiumPkg
MemberAccounts 表(因此此表具有将父级映射到分组在一起的子级 MemberAccounts 的帐户 ID):
AccountId|MembershipNum|MemberType
M1|MN001|Parent
M2|MN001|Parent
M3|MN002|Parent
M4|MN002|Parent
M1|MN003|Child
M1|MN004|Child
M2|MN005|Child
M3|MN006|Child
M4|MN009|Child
M4|MN010|Child
M4|MN011|Child
会员详情表:
AccountId|MemberName
M1|Name1
M2|Name2
M3|Name3
M4|Name4
我的问题是父帐户和子帐户之间的 1:N 关系。父账户下可以有任意数量的子账户。
MN001 成员资格申请示例:
- MembershipNum : MN001
- MemberAccount : M1
- Name: Name1
- ChildAccounts
- MemberAccount : MN003
- MemberAccount : MN004
- MemberAccount : M2
- Name: Name2
- ChildAccounts
-MemberAccount : MN005
我正在使用 Spring Batch,我的应用程序一次处理一个记录。因此,我需要将所有父帐户和子帐户作为一行获取,以填充 JSON 对象(即请求)并将其发布到 Web 服务。
说,我们想使用 Spring Batch 一次处理一个成员。 有人可以帮助我使用 Spring-Batch 中的 SQL 查询/方法来了解我们如何处理这种情况吗?
【问题讨论】:
当然可以,但是到目前为止,您有什么实际上不起作用或需要“注意”? 为了跟进上述内容,您声称我能够获得一个父母:一个孩子帐户记录,但随后每个孩子帐户都会重复该父母帐户。。这样的尝试在哪里?并请显示所需的结果。 【参考方案1】:您可以使用 CTE 和 Dynamic PIVOT 来实现您的要求,如下所示-
DECLARE @cols AS NVARCHAR(MAX),
@sqlCommand AS NVARCHAR(MAX),
@MembershipNum AS NVARCHAR(MAX) = 'MN001' -- Search MembershipNum
;WITH CTE AS
(
SELECT A.MembershipNum MembershipNum,
A.AccountId MemberAccount,
B.MemberName Name,
C.MembershipNum Child,
'Child-'+CAST(ROW_NUMBER() OVER (PARTITION BY A.AccountId ORDER BY C.MembershipNum) AS VARCHAR) C_Name
FROM @MemberAccounts A
INNER JOIN @MemberDetails B ON A.AccountId = B.AccountId
INNER JOIN @MemberAccounts C ON A.AccountId = C.AccountId
WHERE A.MembershipNum = @MembershipNum
AND C.MemberType ='Child'
AND A.MemberType = 'Parent'
)
SELECT @cols =
STUFF((SELECT DISTINCT ( '],[' + A.C_Name)
FROM (SELECT C_Name FROM CTE) A
--ORDER BY A.Child
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')+']'
FROM CTE
--SELECT @cols
SET @sqlCommand=
N'SELECT MembershipNum,MemberAccount,Name,'+SUBSTRING(@cols,2,LEN(@cols))+'
FROM
(
SELECT * FROM (
SELECT A.MembershipNum MembershipNum,
A.AccountId MemberAccount,
B.MemberName Name,
C.MembershipNum Child,
''Child-''+CAST(ROW_NUMBER() OVER (PARTITION BY A.AccountId ORDER BY C.MembershipNum) AS VARCHAR) C_Name
FROM @MemberAccounts A
INNER JOIN @MemberDetails B ON A.AccountId = B.AccountId
INNER JOIN @MemberAccounts C ON A.AccountId = C.AccountId
WHERE A.MembershipNum = '''+@MembershipNum+'''
AND C.MemberType =''Child''
AND A.MemberType = ''Parent''
) your_table
) AS P
PIVOT
(
MAX(Child)
FOR C_Name IN('+SUBSTRING(@cols,2,LEN(@cols))+')
) PVT'
--PRINT @sqlCommand
EXEC (@sqlCommand)
输出会像-
MembershipNum MemberAccount Name Child-1 Child-2
MN001 M1 Name1 MN003 MN004
MN001 M2 Name2 MN005 NULL
【讨论】:
@user9307545 如果真的有帮助,请接受答案并投赞成票:)以上是关于查询获取同一张表中1:N关系的数据的主要内容,如果未能解决你的问题,请参考以下文章
查询同一张表时,spark sql 返回空值,但配置单元和 impaly 获取正常数据?