我已经生成了一个广泛的视图,它根据不同的统计模型模拟某些事件。这些模型在每个列标题中由数字定义,并且行的最大值是最佳模型。获取保存行的最大值的列名称
生成的表格看起来(部分)如下;
+--------+----+------+------+------+------+------+------+
| Number | LI | PHSE | 0505 | 0506 | 0507 | 0508 | 0509 | [...] etc.
+--------+----+------+------+------+------+------+------+
| 100254 | 2 | M1 | 44 | 46 | 45 | 44 | 44 |
| 100254 | 2 | M2 | 36 | 36 | 35 | 37 | 37 |
| 100254 | 2 | M3 | 5 | 5 | 5 | 5 | 5 |
| 100254 | 2 | R1 | 34 | 36 | 37 | 37 | 37 |
| 100254 | 2 | R2 | 41 | 41 | 40 | 41 | 41 |
| 100329 | 1 | M1 | 37 | 38 | 38 | 38 | 39 |
| 100329 | 1 | M2 | 31 | 29 | 28 | 29 | 29 |
| 100329 | 1 | M3 | 6 | 6 | 6 | 6 | 6 |
| 100329 | 1 | R1 | 29 | 29 | 29 | 30 | 30 |
| 100329 | 1 | R2 | 25 | 26 | 26 | 27 | 26 |
+--------+----+------+------+------+------+------+------+
[...] etc.
现在我想找到每个行中的最高值,并显示相应的列名作为这样的;
| Number | LI | PHSE | MAXCOL |
+--------+----+------+--------+
| 100254 | 2 | M1 | 0506 |
| 100254 | 2 | M2 | 0508 |
| 100254 | 2 | M3 | 0505 |
| 100254 | 2 | R1 | 0507 |
| 100254 | 2 | R2 | 0505 |
+--------+----+------+--------+
[...] etc.
这是从100254衍生 - 2 - M1最大值46 0506列发生等
我一直在PIVOT
功能,但没有成功,有玩弄周围。我也寻找一个类似于Excel的索引/匹配等价物,但由于我无法将列标题作为值来引用,所以这显然不起作用(并且还没有找到这样的函数)。
任何帮助将非常感激。每达明的评论
UPDATE:
从代码的摘录,导致此:
SELECT DISTINCT sub2.Number, sub2.LI, sub2.PHSE
, sum(sub2.[0505]) over (partition by sub2.Number, sub2.LI, sub2.PHSE) as '0505'
, sum(sub2.[0506]) over (partition by sub2.Number, sub2.LI, sub2.PHSE) as '0506'
[...] etc. /*64 rows*/
FROM
(SELECT DISTINCT sub.*
, CASE WHEN sub.MF > sub.[5PAV] - sub.[5PSTDEV] THEN 1 ELSE 0 END AS '0505'
, CASE WHEN sub.MF > sub.[5PAV] - sub.[6PSTDEV] THEN 1 ELSE 0 END AS '0506'
[...] etc. /*64 rows*/
FROM
(SELECT DISTINCT ra.*
, sum(ra.qtyr) OVER (partition BY ra.Number, ra.LI, ra.PHSE ORDER BY (ra.Number) rows BETWEEN 5 preceding AND 1 preceding)/
sum(ra.qtyu) OVER (partition BY ra.Number, ra.LI, ra.PHSE ORDER BY (ra.Number) rows BETWEEN 5 preceding AND 1 preceding) AS '5PAV'
, sum(ra.qtyr) OVER (partition BY ra.Number, ra.LI, ra.PHSE ORDER BY (ra.Number) rows BETWEEN 6 preceding AND 1 preceding)/
sum(ra.qtyu) OVER (partition BY ra.Number, ra.LI, ra.PHSE ORDER BY (ra.Number) rows BETWEEN 6 preceding AND 1 preceding) AS '6PAV'
[...] etc. /*8 rows*/
, stdev(ra.MF) OVER (partition BY ra.Number, ra.LI, ra.PHSE ORDER BY (ra.Number) rows BETWEEN 4 preceding AND CURRENT row) AS '5PSTDEV'
, stdev(ra.MF) OVER (partition BY ra.Number, ra.LI, ra.PHSE ORDER BY (ra.Number) rows BETWEEN 5 preceding AND CURRENT row) AS '6PSTDEV'
[...] etc. /*8 rows*/
FROM ra
) AS sub
) AS sub2
毫无疑问,这可能是SQL最无效的用途之一,但时间压力和经验不足使我这样写。
任何建议来更改此代码,并更有效地实现所需的表结果,也将不胜感激。
编辑每安东的答案;
总结为pvt
的上述代码继续如下;
SELECT Number, LI, PHSE, combo, hitrate
FROM (...) AS pvt
UNPIVOT
(Hitrate FOR Combo IN (
[0505],
[0506],
[...] etc.)) AS upvt
伟大的解决方案,一个不雅的问题。
你做了处理数据库表,如果它是一个电子表格的错误。它不是,而且你最终还是a)重复包含相同“类型”数据的列,b)数据不作为数据存储,而是存储在元数据(这里是列名)中。如果您首先正确地建模了数据(模型和值有两列,还有更多行但列较少),查询将很容易编写。 –
@Damien_The_Unbeliever这是有道理的。数据是通过这种格式的子查询生成的,所以源代码不是问题。这是我应用于这一点的方法,似乎无效;尽管'unpivot'按照您的建议重新排列了数据,但这似乎是一种非常无效的绕行方式。我将编辑上面的问题来缩小这个范围,看看代码如何变得更高效。考虑到所有涉及的变量,我已经尽可能在Excel中使用聚合函数来编写查询。我知道这很愚蠢,但时间压力和有限的经验让我想到这个方法 – Sambo