【问题标题】:Percentage based on criteria in column基于列中标准的百分比
【发布时间】:2018-04-17 14:12:06
【问题描述】:

我想弄清楚如何在下表底部获得百分比行。

SD    a    b     c        d       e
D   2168 1545   2163    1540    2153
S   435   212   410      193    391
T   13208 5438  12935   5337    12656

我想将 D 行和 S 行除以 T 行来创建两个新的百分比行。这可能吗? 输出如下所示:

 SD   a       b      c        d       e
D   2168    1545    2163    1540    2153
S   435      212    410      193    391
T   13208    5438   12935   5337    12656
D/T 0.164    0.284  0.167   0.288   0.170
S/T 0.033    0.04   0.032   0.04    0.031

我只需要百分比,所以不一定需要在表格中,但如果是的话,那也没关系。

TIA。

【问题讨论】:

  • 到目前为止你尝试过什么?如果您要混合聚合数据和非聚合数据,则在表示层中这样做可能会更好。
  • 表中只有这些行吗?
  • @scsimon 是的,但如果您使用的是ROLLUP,那么您已经在使用聚合数据(以及GROUP BY 子句)。我确实说过如果您正在混合聚合和非聚合。 :)
  • @scsimon,如果不是,它们很容易成为 CTE 中唯一的行。

标签: sql sql-server sql-server-2017


【解决方案1】:

这很麻烦,但它可以用你的表名替换#temp

select *, row_number() over (order by SD)rownum into #temp2 from #temp 


select *from #temp2   
union
select 'D/T',(select a from #temp2 where sd='D')/ cast((select a from #temp2 where sd='T')  as float),
 (select b from #temp2 where sd='D')/ cast((select b from #temp2 where sd='T')  as float),
  (select c from #temp2 where sd='D')/ cast((select c from #temp2 where sd='T')  as float),
 (select d from #temp2 where sd='D')/ cast((select d from #temp2 where sd='T')  as float),
 (select e from #temp2 where sd='D')/ cast((select e from #temp2 where sd='T')  as float), 
 (select max(rownum)+1 from #temp2)
 union
select 'S/T',(select a from #temp2 where sd='S')/ cast((select a from #temp2 where sd='T')  as float),
 (select b from #temp2 where sd='S')/ cast((select b from #temp2 where sd='T')  as float),
  (select c from #temp2 where sd='S')/ cast((select c from #temp2 where sd='T')  as float),
 (select d from #temp2 where sd='S')/ cast((select d from #temp2 where sd='T')  as float),
 (select e from #temp2 where sd='S')/ cast((select e from #temp2 where sd='T')  as float), 
 (select max(rownum)+2 from #temp2)
 order by rownum

【讨论】:

    【解决方案2】:

    你可以这样做:

    select t.sd, t.a, t.b, t.c, t.d, t.e
    from t
    union all
    select sd.sd + '/T', sd.a * 1.0 / t.a, sd.b * 1.0 / t.b, sd.c * 1.0 / t.c,
           sd.d * 1.0 / t.d, sd.e * 1.0 / t.d
    from t sd cross join
         (select t2.* from t t2 where sd = 'T') tt
    where sd in ('D', 'S');
    

    虽然实际上这会按您想要的顺序返回行,但这并不能保证。另请注意,最后的列都将具有相同的类型。

    【讨论】:

    • 嗨,戈登,我想试试这个,我对交叉连接中的 t2.* 部分感到困惑。你从哪里得到t2?你的意思是 (select t.* from t where sd = 'T') ??谢谢
    猜你喜欢
    • 2020-12-09
    • 2021-09-10
    • 2023-03-31
    • 2019-06-03
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    相关资源
    最近更新 更多