很难说出这个问题。如果有更好的标题,请告诉我。
我有一个产生如下数据的查询:
def show(x: Option[String]) = x match {
case Some(s) if(s.head.isUpper) => s
case None => "No value"
}
或者,我可以生成这样的数据:
+----------+----------+----------+----------+----------+
| KEY | FEB_GRP1 | JAN_GRP1 | FEB_GRP2 | JAN_GRP2 |
+----------+----------+----------+----------+----------+
| 50840992 | 1 | 1 | 0 | 0 |
| 50840921 | 0 | 1 | 1 | 0 |
| 50848995 | 0 | 0 | 0 | 0 |
+----------+----------+----------+----------+----------+
其中< 50应该反击"第1组"和〜< 50应该作为"组2"。
我希望它是这样的:
+----------+------+------+
| KEY | JAN | FEB |
+----------+------+------+
| 50840992 | <50 | ~<50 |
| 50840921 | <50 | <50 |
| 50848995 | ~<50 | ~<50 |
| 50840885 | <50 | <50 |
+----------+------+------+
我只能通过对JAN_GRP1求和得到JAN_GRP1_SUM,但我希望它只是一个数据点,而不是列本身。
我的查询(生成第一张图):
+-------+------+------+
| MONTH | GRP1 | GRP2 |
+-------+------+------+
| JAN | 2 | 0 |
| FEB | 1 | 1 |
+-------+------+------+
答案 0 :(得分:2)
您的数据模型没有多大意义,但从您展示的内容中可以做到:
select 'JAN' as month,
count(case when "JAN-1-2016" = '<50' then 1 end) as grp1,
count(case when "JAN-1-2016" != '<50' then 1 end) as grp2
from my_table
union all
select 'FEB' as month,
count(case when "FEB-1-2016" = '<50' then 1 end) as grp1,
count(case when "FEB-1-2016" != '<50' then 1 end) as grp2
from my_table;
这不能很好地扩展 - 如果你有更多的月份需要为每一个添加另一个联合分支。
如果您的查询基于视图或之前计算的摘要,那么返回原始数据可能会容易得多。
如果你坚持这一点,那么另一种可能的方法,如果你实际上有两个多月的时间可能会更容易管理,可能是取消数据的转移:
select *
from my_table
unpivot(value for month in ("JAN-1-2016" as date '2016-01-01',
"FEB-1-2016" as date '2016-02-01') --, etc. for other months
);
然后聚合:
select to_char(month, 'MON', 'NLS_DATE_LANGUAGE=ENGLISH') as month,
count(case when value = '<50' then 1 end) as grp1,
count(case when value != '<50' then 1 end) as grp2
from (
select *
from my_table
unpivot(value for month in ("JAN-1-2016" as date '2016-01-01',
"FEB-1-2016" as date '2016-02-01') --, etc. for other months
)
)
group by month;
仍然不是很漂亮,Oracle在我认为的内容中做了几乎相同的事情,但是创建和维护的案例表达式更少 - 苦差事部分是非对话。您可能需要在“月份”字段中包含年份,具体取决于您拥有的数据范围。