1

我有 2 温度。看起来像这样的表

@t1(p_ssn,p_fname,p_lname,Gender,.............) -> 这个表有员工记录,大约有30 列

@t2(p_ssn,benefit,medical_premium,dental_premium,..............)-> 此表有员工福利,大约有60 列

中的每条记录@t1都会有 1 个或多个对应的记录@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 

现在,我正在使用循环。但是由于每条记录都比较大,走一半就挂了。


@Tim - 这就是我卡住的地方。@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

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

4

2 回答 2

0

我的假设是您的输出是连接字段(例如 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”

于 2012-08-30T01:05:06.490 回答
0

你最终可能会做这样的事情:

-- 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

诀窍是生成ordinal我们稍后可以排序的列。

但是,我通常建议不要在数据库引擎中创建这样的报告,因为这就是您的 Web/应用服务器上的报告工具和前端代码的用途(这些通常可以更好地扩展)。另外,小心使用SSN 作为主键

于 2012-08-28T16:36:12.873 回答