Tsql 如何在连接两个表时显示不同行中的数据

Tsql 如何在连接两个表时显示不同行中的数据,tsql,Tsql,我有两个临时工。看起来像这样的桌子 @t1(p\u ssn、p\u fname、p\u lname、性别等)->此表包含员工记录,约有30列 @t2(p\u ssn、福利、医疗保险费、牙科保险费等)->此表包含员工福利,约有60列 @t1中的每个记录在@t2中将有一个或多个对应记录 如何在表之间进行联接以获得这样的显示(在p_ssn上联接) 我想要每个员工的记录,然后是他们的所有福利记录-每个记录在不同的行上,如图所示 p_fname,p_lname,Gender etc... -&g

我有两个临时工。看起来像这样的桌子

@t1(p\u ssn、p\u fname、p\u lname、性别等)
->此表包含员工记录,约有30列

@t2(p\u ssn、福利、医疗保险费、牙科保险费等)
->此表包含员工福利,约有60列

@t1
中的每个记录在
@t2
中将有一个或多个对应记录

如何在表之间进行联接以获得这样的显示(在p_ssn上联接) 我想要每个员工的记录,然后是他们的所有福利记录-每个记录在不同的行上,如图所示

p_fname,p_lname,Gender etc...      -> 1st employee
benefit1,medical_premium1,dental_premium_1     -> all the benefit records for this employee
p_fname,p_lname,Gender etc...      -> 2nd  employee
benefit1,medical_premium1,dental_premium_1 
现在,我正在使用一个循环。但由于每张唱片的尺寸都很大,所以在播放了一半之后就挂断了


@蒂姆-这就是我被困的地方@t1只有30列,但@t2有60列

--实际查询

    select col1, col2 from 
(     -- Get employees     
 select 10 as ordinal, p_ssn, p_fname as col1, p_lname as col2,**there are only 30 columns here**     
 from @t1     
union all    
 -- Get benefits     
select 20 as ordinal, a.p_ssn, cast(b.benefit as varchar(50)), cast(b.premium as varchar(50)) ,**I want to display more columns here like b.col1,b.col2,b.col3 etc...60 columns**    
from @t1 a         
 join @t2 b on a.p_ssn = b.p_ssn ) as a order by p_ssn, ordinal 
我知道我可以做到以下几点

  select 10 as ordinal, p_ssn, p_fname as col1, p_lname as col2,'','',''
from @t1
 union all
select 20 as ordinal, a.p_ssn, cast(b.benefit as varchar(50)), cast(b.premium as varchar(50)),b.col1,b.col2,n.col3

但这是一个文件提要,不允许空白。事实上,我无法使用转换,因为长度和数据类型已定义,无法更改

您可能会执行以下操作:

-- Setup demo data
declare @t1 table (
      p_ssn char(11) not null primary key
    , p_fname varchar(50) not null
    , p_lname varchar(50) not null
)
insert into @t1 select '000-00-0000', 'Joe', 'Blow'
insert into @t1 select '111-11-1111', 'Jane', 'Doe'
declare @t2 table (
      p_ssn char(11) not null
    , benefit varchar(50)
    , premium int
)
insert into @t2 select '000-00-0000', 'Benefit 1', 100
insert into @t2 select '000-00-0000', 'Benefit 2', 200
insert into @t2 select '111-11-1111', 'Benefit 1', 300
insert into @t2 select '111-11-1111', 'Benefit 2', 400

-- Actual query
select col1, col2
from (
    -- Get employees
    select 10 as ordinal, p_ssn, p_fname as col1, p_lname as col2
    from @t1
    union all
    -- Get benefits
    select 20 as ordinal, a.p_ssn, cast(b.benefit as varchar(50)), cast(b.premium as varchar(50))
    from @t1 a
        join @t2 b on a.p_ssn = b.p_ssn
) as a
order by p_ssn, ordinal
col1        col2
Joe         Blow
Benefit 1   100
Benefit 2   200
Jane        Doe
Benefit 1   300
Benefit 2   400
要获得如下输出:

-- Setup demo data
declare @t1 table (
      p_ssn char(11) not null primary key
    , p_fname varchar(50) not null
    , p_lname varchar(50) not null
)
insert into @t1 select '000-00-0000', 'Joe', 'Blow'
insert into @t1 select '111-11-1111', 'Jane', 'Doe'
declare @t2 table (
      p_ssn char(11) not null
    , benefit varchar(50)
    , premium int
)
insert into @t2 select '000-00-0000', 'Benefit 1', 100
insert into @t2 select '000-00-0000', 'Benefit 2', 200
insert into @t2 select '111-11-1111', 'Benefit 1', 300
insert into @t2 select '111-11-1111', 'Benefit 2', 400

-- Actual query
select col1, col2
from (
    -- Get employees
    select 10 as ordinal, p_ssn, p_fname as col1, p_lname as col2
    from @t1
    union all
    -- Get benefits
    select 20 as ordinal, a.p_ssn, cast(b.benefit as varchar(50)), cast(b.premium as varchar(50))
    from @t1 a
        join @t2 b on a.p_ssn = b.p_ssn
) as a
order by p_ssn, ordinal
col1        col2
Joe         Blow
Benefit 1   100
Benefit 2   200
Jane        Doe
Benefit 1   300
Benefit 2   400
诀窍是生成我们以后可以排序的
有序列


我通常会建议不要在数据库引擎中创建这样的报告,但是,这正是web/app服务器上的报告工具和前端代码的用途(它们通常具有更好的扩展性)。另外,请注意。

我的假设是,您的输出是串联字段(例如,p_lname+','+p_fname)。这可能是一个可行的解决方案:

declare @tmpResult table(GroupRankNo int
                        , Name nvarchar(100)
                        , Benefits nvarchar(500)
                        , SSN int)

insert into @tmpResult table(GroupRankNo
                            , Name
                            , Benefits
                            , SSN)
select row_number() over(partition by aa.Name order by aa.Name) as GroupRankNo
        , aa.Name
        , aa.Benefits
        , aa.p_ssn
from
(       
    select a.p_fname + ', ' + a.p_lname as Name
            , b.benefit + ', ' + b.premium as Benefits
            , a.p_ssn
    from @t1 a
    inner join @t2 b on b.p_ssn = a.p_ssn
) aa                                


select aa.ColumnData
from
(
    select SSN
            , Name as ColumnData
            , 0 as RowType --Header
    from @tmpResult
    where GroupRankNo = 1

    union

    select SSN
            , Benefits as ColumnData
            , 1 as RowType --Detail
    from @tmpResult
) aa
order by aa.SSN
            , RowType asc

我还没有测试过。但是你会明白,使用“row_number()over partition by”

上面的问题是我不能使用UNION,因为雇员和福利表的字段数不同,它们是完全不同的。我写的只是一个样本,很有趣。我认为只要选择相同数量的列(而不是
select*
)并转换为相同的数据类型,就应该能够合并。您希望在查询中获得更多列吗?表t1大约有60列,而t2大约有35列。所以我必须选择t2中的空白列来进行联合。这不是我想要的我想我真的不明白这个问题。你能修改一下你的问题来更清楚地说明你想要什么吗?谢谢你的帮助。我已经编辑并在问题的末尾添加了一个注释。请注意,返回结果的方式与显示结果的方式完全不同,这实际上不是查询的工作。发出查询时,您是在查询数据,而不是数据的外观。表示层应该负责如何向用户显示数据。请指定输出文件的格式。固定宽度或分隔符,#cols等。感谢您的回复。请参阅我在问题末尾为@Tim添加的评论。在你上面的查询中,我将遇到与工会相同的问题。看起来像一个文件提要。文件的格式应该是什么?只要您知道所需的分隔符,将字段连接到一个字段中可能就行了。在这种情况下,“联合”就不会有问题了。这是个好主意——从未想过要连接字段。谢谢。我会试试的