【问题标题】:How to combine multiple rows from 4 tables into one single row in a new table in SQL?如何在 SQL 的新表中将 4 个表中的多行合并为一行?
【发布时间】:2017-11-20 04:53:54
【问题描述】:

大家好,我叫 Penelope,我有大约 4 年的 SQL 经验。首先,我要感谢你们花时间阅读本文,然后提供方向、示例、步行或指导。 我有一个我无法弄清楚的 SQL 问题/难题。我尝试将几条记录连接到记录中,但没有成功。我对 Joins 有一些经验,但这似乎有点超出我的想象,我希望能得到一点帮助或指导。我只想要一个长的学生记录,但正如您所看到的,我得到了正确的数据,但是正在创建多条记录,因为有些表有不止一条记录。您可以在下面看到我需要作为一条记录插入到名为 EntireStudentI 的表中的表和列的名称。我的 SQL 和我当前的结果 我有一个名为 TP 的表,它在一条记录中为我提供了有关学生的基本信息

trans_type
trk_link
service_db     
scn
given_nm
surname_nm
cc
sex
grade
dob
marital_st
pob_city
pob_cntry
UScitizenship_CD

我有一张名为 P 的表,它会给我一个记录,我需要护照号码

pass_nbr

我有一个名为 VI 的表,它可以给我多个记录,因为学生可以拥有多个签证

pass_nbr - 与护照中的名称相同,但在本例中是 Visa Number,因此在我的 SQL 中,我将其设置为 VisaNo,以减少混淆。这可以是没有记录,一,二……

最后我有一张名为 PD 的表格,它是学生的家属/家庭成员。这可以是没有记录,一,二……

given_nm 和 surname_nm(这些将被连接成 DepName)

dep_rel
birth-dt

我想要做的是有一条记录,其中包含上面列出的 TP 列。

然后将 pass_nbr 添加为 P 表中的列。

然后将 VI 表中的 VisaNo(s) 添加为逗号分隔的列 -VisaNo 可以为空白,或者一个 VisaNo 或多个 VisaNo。示例将是一个空列值,即一个数字。 89888 或多个值 89888,78908,78999。

最后,我想从 PD 表中添加相关信息列。学生不需要有受抚养人,或者他们可以有多个受抚养人,例如配偶和孩子 - 配偶和孩子将创建两个记录,即 PD 表中的两个单独记录。在我的单条记录中,我希望有列分隔的 Depname、列分隔的 dep_rel 和逗号分隔的birth_dt

所有这些表都通过一个名为 trk_link 的列联系在一起,这是关键

这是我的 SQL

SELECT t.trans_type
      ,t.trk_link
      ,t.service_db     
      ,t.scn
      ,t.given_nm
      ,t.surname_nm
      ,t.cc
      ,t.sex
      ,t.grade
      ,t.dob
      ,t.marital_st
      ,t.pob_city
      ,t.pob_cntry
      ,CASE t.UScitizenship_CD
          WHEN 'H' THEN 'Holds'
          WHEN 'DNH' THEN 'Does Not Hold'
          else ''
          End as Student_Citizenship_Status

      --,t.UScitizenship_CD
      ,t.trk_link20
      ,p.pass_nbr
      ,v.pass_nbr as VisaNo,
      CONCAT(p2.given_nm, ' ', p2.surname_nm) As DepName
      --,p2.given_nm
      --,p2.surname_nm
      ,p2.dep_rel
      ,p2.birth_dt
      ,CASE p2.UScitizenship_CD
          WHEN 'H' THEN 'Holds'
          else 'Does Not Hold'
          End as Dependent_Citizenship_Status

from TP t
inner join P p
on t.[trk_link] = p.[trk_link]

inner Join VI v

on p.[trk_link] = v.[trk_link]

inner join PD p2
on t.[trk_link] = p2.[trk_link]

where t.trk_link = '22985200458053000003171117104111'

这就是结果

非常感谢各位 佩内洛普!`

【问题讨论】:

    标签: sql-server database join sql-server-2012


    【解决方案1】:

    有很多方法可以实现这一点。您可以使用STUFFXML PATH,也可以使用用户定义的函数。

    最简单的方法是添加用户定义的函数并在任何你想要的地方使用它。你甚至不必创建函数。它已经在GROUP_CONCAT string aggregate for SQL Server 可用。

    您可以按如下方式使用它:

    SELECT some_id,
           dbo.GROUP_CONCAT(some_column) AS as delimited_list
    FROM dbo.some_table
    GROUP BY some_id;
    

    它给出如下输出:

    some_id           delimited_list
    ----------------- -----------------------------------
    1                 red,green,blue
    2                 cyan,magenta,yellow,key
    

    你可以试试我之前说的STUFFXML PATH

    SELECT t.trans_type
          ,t.trk_link
          ,t.service_db     
          ,t.scn
          ,t.given_nm
          ,t.surname_nm
          ,t.cc
          ,t.sex
          ,t.grade
          ,t.dob
          ,t.marital_st
          ,t.pob_city
          ,t.pob_cntry
          ,CASE t.UScitizenship_CD
              WHEN 'H' THEN 'Holds'
              WHEN 'DNH' THEN 'Does Not Hold'
              else ''
              End as Student_Citizenship_Status
    
          --,t.UScitizenship_CD
          ,t.trk_link20
          ,p.pass_nbr
          --,v.pass_nbr as VisaNo,
          ,STUFF((SELECT VisaNo  
                   from VI as v
                   where v.[trk_link]=p.[trk_link] 
                   FOR XML PATH('')),1,1,'') as VisaNumbers
          ,CONCAT(p2.given_nm, ' ', p2.surname_nm) As DepName
          --,p2.given_nm
          --,p2.surname_nm
          ,p2.dep_rel
          ,p2.birth_dt
          ,CASE p2.UScitizenship_CD
              WHEN 'H' THEN 'Holds'
              else 'Does Not Hold'
              End as Dependent_Citizenship_Status
    
    from TP t
    inner join P p
    on t.[trk_link] = p.[trk_link]
    --inner Join VI v
    --on p.[trk_link] = v.[trk_link]  
    inner join PD p2 on t.[trk_link] = p2.[trk_link]
    where t.trk_link = '22985200458053000003171117104111'
    

    注意:在描述中,VisNumber 在v 表中保存为VisaNo。但在您的查询中,您尝试选择pass_nbr。所以,我不确定它是如何保存在你的数据库中的。相应地进行更改。

    【讨论】:

    • 谢谢吉斌!!第二个稍加调整的例子给了我我需要的东西。佩内洛普
    • @PenelopeEstes 我很高兴它为你解决了。您可以考虑将此标记为正确答案,以便对引用此问题的其他人有用。
    猜你喜欢
    • 1970-01-01
    • 2016-03-07
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多