查询获取同一张表中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 获取正常数据?

如何获取同一张表中不同类别的布尔值的比例

SQL Server:如何为同一张表中的不同客户获取 3 天内的滚动总和

使用 Android 房间数据库在同一张表中的一对多关系

想请教下在oracle中如何实现获取一张表中,设定开始时间和结束时间,并且根据时间间隔来查询出来的数据。