0

想象以下两个表:

create table MainTable (
  MainId integer not null, -- This is the index
  Data varchar(100) not null
)

create table OtherTable (
  MainId integer not null,    -- MainId, Name combined are the index.
  Name varchar(100) not null,
  Status tinyint not null
)

现在我想从 中选择所有行MainTable,同时将与每个匹配的所有行组合MainIdOtherTable结果集中的单个字段中。

想象一下数据:

MainTable:
1, 'Hi'
2, 'What'

OtherTable:
1, 'Fish', 1
1, 'Horse', 0
2, 'Fish', 0

我想要这样的结果集:

MainId, Data,   Others
1,      'Hi',   'Fish=1,Horse=0'
2,      'What', 'Fish=0'

最优雅的方法是什么?

(不要担心逗号在结果字符串的前面或末尾。)

4

2 回答 2

1

在 Sybase 中没有真正优雅的方法可以做到这一点。不过,这是一种方法:

select 
  mt.MainId, 
  mt.Data,
  Others = stuff((
             max(case when seqnum = 1 then ','+Name+'='+cast(status as varchar(255)) else '' end) +
             max(case when seqnum = 2 then ','+Name+'='+cast(status as varchar(255)) else '' end) +
             max(case when seqnum = 3 then ','+Name+'='+cast(status as varchar(255)) else '' end)
           ), 1, 1, '')
from MainTable mt 
  left outer join
    (select 
       ot.*, 
       row_number() over (partition by MainId order by status desc) as seqnum
     from OtherTable ot
    ) ot
    on mt.MainId = ot.MainId
group by
  mt.MainId, md.Data

也就是说,它枚举了第二个表中的值。然后它进行条件聚合以获取每个值,使用该stuff()函数处理额外的逗号。以上适用于前三个值。如果你想要更多,那么你需要添加更多的子句。

于 2013-08-19T14:49:08.510 回答
0

好吧,这就是我在 Sybase 13.x 中实现它的方式。该代码的优点是不限于多个Names。

create proc
as
  declare
    @MainId int,
    @Name   varchar(100),
    @Status tinyint

  create table #OtherTable (
    MainId     int          not null,
    CombStatus varchar(250) not null
  )

  declare OtherCursor cursor for
    select
        MainId, Name, Status
      from
        Others

  open OtherCursor
    fetch OtherCursor into @MainId, @Name, @Status
    while (@@sqlstatus = 0) begin -- run until there are no more
      if exists (select 1 from #OtherTable where MainId = @MainId) begin
        update #OtherTable
          set CombStatus = CombStatus + ','+@Name+'='+convert(varchar, Status)
          where
            MainId = @MainId
      end else begin
        insert into #OtherTable (MainId, CombStatus)
          select
            MainId = @MainId,
            CombStatus = @Name+'='+convert(varchar, Status)
      end

      fetch OtherCursor into @MainId, @Name, @Status
    end
  close OtherCursor

  select
      mt.MainId,
      mt.Data,
      ot.CombStatus
    from
      MainTable mt
        left join #OtherTable ot
          on mt.MainId = ot.MainId

但它确实有使用游标和工作表的缺点,至少在大量数据的情况下,这会使整个过程变慢。

于 2013-08-22T11:47:02.877 回答