2014-09-30 208 views
0

我有以下含关于每个组是如何解决问题的数据表:重新排序

PROB | GROUP | REPNO | STATUS 
-----+---------+-------+------- 
1 | Juniors | 0 | 
1 | Seniors | 1 | 
1 | Juniors | 2 | 
1 | Experts | 3 | SOLVED 
2 | Juniors | 0 | 
2 | Seniors | 1 | SOLVED 

柱PROB定义了基团中解决问题,列组定义组正在研究这一概率其中,柱REPNO定义解决重复的次数(重复尝试直到最终解决,0表示首先尝试,不重复),最后一列STATUS定义是否在该特定尝试中解决了任务。在这里,我可以通过所有群组(SELECT ... GROUP BY repno)在每次重复中有效地解决工作问题。

但我想说明probs是如何有效地解决每个特定的组(每组自己的重复顺序分布)。例如,PROB 1被小组试验了2次,并且一次被老年人组解决,最终在小组专家的第一次尝试中得到解决。

所以我需要重复的重新计算对于每个特定组:

PROB | GROUP | REPNO | REPNO_J | REPNO_S | REPNO_E | STATUS 
-----+---------+-------+---------+---------+---------+------- 
1 | Juniors | 0 |  0 |   |   | 
1 | Seniors | 1 |   |  0 |   |   
1 | Juniors | 2 |  1 |   |   |   
1 | Experts | 3 |   |   |  0 | SOLVED <-- experts solved in first try 
2 | Juniors | 0 |  0 |   |   | 
2 | Seniors | 1 |   |  0 |   | SOLVED <-- seniors solved in first try 

如何让这个重新计算?

+0

它是固定的,你有** 3个**组或将要在组号码各不相同情况呢? – 2014-09-30 14:53:31

+0

组数不会有所不同。 – sbrbot 2014-09-30 18:43:53

+0

是否有任何公布的答案可供您使用,或者您是否有其他想法? – 2014-09-30 18:49:21

回答

1

使用RANK()SQL FIDDLE

select 
    PROB, 
    GROUP1, 
    REPNO, 
    DECODE(GROUP1,'Juniors', rank() over (partition by prob, group1 order by repno) - 1) as REPNO_J, 
    DECODE(GROUP1,'Seniors', rank() over (partition by prob, group1 order by repno) - 1) as REPNO_S, 
    DECODE(GROUP1,'Experts', rank() over (partition by prob, group1 order by repno) - 1) as REPNO_E, 
    STATUS 
from mytable 
order by prob,repno 
+0

谢谢@Jaugar Chang,这是非常优雅的解决方案。更重要的是,你在SQLfiddle中提供了一个例子,你是唯一的例子。 – sbrbot 2014-09-30 19:17:24

0

可以使用CASE语句

SELECT "PROB", 
     "GROUP", 
     "REPNO", 
     (CASE WHEN "GROUP" = 'Juniors' THEN REPNO ELSE NULL END) as REPNO_J, 
     (CASE WHEN "GROUP" = 'Seniors' THEN REPNO ELSE NULL END) as REPNO_S, 
     (CASE WHEN "GROUP" = 'Experts' THEN REPNO ELSE NULL END) as REPNO_E 
FROM Table1 
+0

当需要检查的条件过多时,“CASE”不可行。更好地使用'ANALYTIC'函数来处理每个'group'中的顺序,如'PARTITION BY'子句中提到的那样。 – 2014-09-30 15:37:19

+0

@LalitKumarB,你可以用ANALYTIC函数详细说明或给出解决方案 – radar 2014-09-30 18:24:07

+0

看看Thorsten的答案。另外,你会写多少个CASE条件? – 2014-09-30 18:37:17

1

使用ROW_NUMBER窗函数来获得每组人数:

select 
    prob, 
    "GROUP", 
    repno, 
    case when "GROUP" = 'Juniors' then try end as repno_j, 
    case when "GROUP" = 'Seniors' then try end as repno_s, 
    case when "GROUP" = 'Experts' then try end as repno_e, 
    status 
from 
(
    select 
    prob, "GROUP", repno, status, 
    row_number() over(partition by prob, "GROUP" order by repno) - 1 as try 
    from mytable 
) 
order by prob, repno; 

顺便说一句:这不是一个好主意,名称的列组。这是SQL中的保留字。因此,您必须使用引号并在查询中使用该名称时考虑大写/小写。

+0

更好的解决方案。 'ANALYTIC'负责处理每个组中的顺序,如'PARTITION' BY子句中所述。 – 2014-09-30 15:38:16

+0

此解决方案正常工作。 @Lalit Kumar B,你已经在这里给出了三条评论推荐ANALYTIC,请给我们你的解决方案,不仅仅是评论。我们希望看到它。 – sbrbot 2014-09-30 19:03:11

+0

@sbrbot,'我们希望看到它'你说** **我是谁?你问了这个问题,人们已经回应。我不得不说的是技术上的回答。所以,我刚才就这个答案和我的意见一起评论了为什么分析更好。我希望你得到你的答案,我的意见会帮助你理解**为什么这是更好的解决方案。你在哪里看到三条评论?看到你作为提问者的讲话语气真是令人惊讶。 – 2014-09-30 19:08:32