Sql 获取单行中不同的列值

Sql 获取单行中不同的列值,sql,oracle,oracle10g,pivot,unpivot,Sql,Oracle,Oracle10g,Pivot,Unpivot,以下是数据: id name period data1 data2 =================================================== 111 name1 monthly aaaaa bbbbb 111 name1 quaterly ccccc ddddd 111 name1 halfYearly eeeee fffff 111 name1 annually

以下是数据:

id    name     period      data1    data2
===================================================
111   name1    monthly     aaaaa    bbbbb
111   name1    quaterly    ccccc    ddddd
111   name1    halfYearly  eeeee    fffff
111   name1    annually    ggggg    hhhhh
我想要一个在一行中获取数据的查询,比如

id    name     monthlYdata1    monthlYdata2      quaterlydata1    quaterlydata2      halfYearlydata1    halfYearlydata2      annuallydata1    annuallydata2
==========================================================================================================================================================
111   name1    aaaaa           bbbbb             ccccc            ddddd              eeeee              fffff                ggggg            hhhhh

从查询本身获取数据


从查询1中获取id和名称,并使用从查询1中获取的id将该查询与月度、季度和年度数据连接起来。三篇完整文章用于您的问题:

select *
from
(
  select id, name, value, 
    period||data new_col
  from yourtable
  unpivot
  (
    value for data in (data1, data2)
  ) u
) x
pivot
(
  max(value)
  for new_col in ('monthlyDATA1', 'monthlyDATA2',
                  'quaterlyDATA1', 'quaterlyDATA2',
                  'halfYearlyDATA1', 'halfYearlyDATA2',
                  'annuallyDATA1', 'annuallyDATA2')
) p


首先,您应该将所有差异id检索到临时表中

Select DISTINCT id
into #tmpIds
from Table
然后创建一个包含所需列的时态表(
id
name
monthlYdata1
monthlYdata2
quaterlydata1
quaterlydata2
halfYearlydata1
annuallydata1
annuallydata2
),并循环遍历第一个临时表以获取id

对于每个id,您应该执行以下操作:

Insert into #tmpTable
   @id,
   '',
  (Select data1 from Table where id=@id and period='monthly') as monthlyData1
  ...

这是我想到的第一个解决方案。

您没有指定正在使用的RDBMS,但是,这将在所有RDBMS中都起作用:

select id,
  name,
  max(case when period = 'monthly' then data1 end) as MonthlyData1,
  max(case when period = 'monthly' then data2 end) as MonthlyData2,
  max(case when period = 'quaterly' then data1 end) as quarterlyData1,
  max(case when period = 'quaterly' then data2 end) as quarterlyData2,
  max(case when period = 'halfYearly' then data1 end) as halfYearlyData1,
  max(case when period = 'halfYearly' then data2 end) as halfYearlyData2,
  max(case when period = 'annually' then data1 end) as annuallyData1,
  max(case when period = 'annually' then data2 end) as annuallyData2
from yourtable
group by id, name

如果您使用的RDBMS具有
PIVOT
功能,则可以执行以下操作,使用
UNPIVOT
PIVOT
生成结果。正如Andrey M所指出的,
UNPIVOT
假设
data1
data2
的数据类型是相同的,如果不是,则需要将数据转换为
UNPIVOT

id    name     period      data1    data2
===================================================
111   name1    monthly     aaaaa    bbbbb
111   name1    quaterly    ccccc    ddddd
111   name1    halfYearly  eeeee    fffff
111   name1    annually    ggggg    hhhhh
Oracle 11g:

select *
from
(
  select id, name, value, 
    period||data new_col
  from yourtable
  unpivot
  (
    value for data in (data1, data2)
  ) u
) x
pivot
(
  max(value)
  for new_col in ('monthlyDATA1', 'monthlyDATA2',
                  'quaterlyDATA1', 'quaterlyDATA2',
                  'halfYearlyDATA1', 'halfYearlyDATA2',
                  'annuallyDATA1', 'annuallyDATA2')
) p

SQL Server:

select *
from
(
  select id, name, value, 
    period+data new_col
  from yourtable
  unpivot
  (
    value for data in (data1, data2)
  ) u
) x
pivot
(
  max(value)
  for new_col in ('monthlyDATA1', 'monthlyDATA2',
                  'quaterlyDATA1', 'quaterlyDATA2',
                  'halfYearlyDATA1', 'halfYearlyDATA2',
                  'annuallyDATA1', 'annuallyDATA2')
) p

您使用的是哪种数据库管理系统?Oracle版本11或更高版本具有PIVOT命令,可以完全执行您想要的操作。您可能应该规定,您的UNPIVOT/PIVOT查询假定
data1
data2
属于同一类型。@AndriyM同意,并发布了一条注释。一吨谢谢。。我刚刚删除了聚合函数max()&它成功地工作了:):)