将相同排名放在相似值中

时间:2016-06-22 14:18:18

标签: oracle

我有这种格式的数据。

    ID Group    Flag
    1    A        Y
    2    A        Y
    3    A        Y
    4    A        Y
    5    A        N
    6    A        N
    7    A        N
    8    B        N
    9    B        Y
   10    B        Y
   11    B        Y
   12    B        N
   13    B        N
   14    B        N

我希望按以下顺序获取变量的排名。

  ID Group      Flag    Rank
  1    A         Y       1
  2    A         Y       1
  3    A         Y       1
  4    A         Y       1
  5    A         N       0
  6    A         N       0
  7    A         N       0
  8    B         N       0
  9    B         Y       2
 10    B         Y       2
 11    B         Y       2
 12    B         N       0
 13    B         Y       3
 14    B         Y       3

有谁能告诉我如何得到这个结果?

上述结果中特定顺序的原因摘要:
 我想为Flag =“Y”的每个组取最大值。只有在连续出现时才会选择这些值。例如,在B的情况下,我将获得2个最大值而不是1.因此,我们的想法是区分每个组中的标志

测试数据:

CREATE TABLE #TEST
(
GROUPP VARCHAR(2),
fLAG VARCHAR(2)
)

INSERT INTO #TEST
SELECT    'A',       'Y' UNION ALL
SELECT    'A',       'Y' UNION ALL
SELECT    'A',       'Y' UNION ALL
SELECT    'A',       'Y' UNION ALL
SELECT    'A',       'N' UNION ALL
SELECT    'A',       'N' UNION ALL
SELECT    'A',       'N' UNION ALL
SELECT    'B',       'N' UNION ALL
SELECT    'B',       'Y' UNION ALL
SELECT    'B',       'Y' UNION ALL
SELECT    'B',       'Y' UNION ALL
SELECT    'B',       'N' UNION ALL
SELECT    'B',       'N' UNION ALL
SELECT    'B',       'N' 

3 个答案:

答案 0 :(得分:1)

这应该让你开始。 但我刚刚意识到你希望以另一种方式确定等级,而不是我最初的想法。

CREATE TABLE #test
(
    ID int not null, 
    [group] char not null, 
    flag char not null
)

INSERT INTO #test
SELECT 1, 'A', 'Y'
UNION
SELECT 2, 'A', 'Y'
UNION
SELECT 3, 'A', 'Y'
UNION
SELECT 4, 'A', 'Y'
UNION
SELECT 5, 'A', 'N'
UNION
SELECT 6, 'A', 'N'
UNION
SELECT 7, 'A', 'N'
UNION
SELECT 8, 'B', 'N'
UNION
SELECT 9, 'B', 'Y'
UNION
SELECT 10, 'B', 'Y'
UNION
SELECT 11, 'B', 'Y'
UNION
SELECT 12, 'B', 'N'
UNION
SELECT 13, 'B', 'N'
UNION
SELECT 14, 'B', 'N'


select *
from #test

SELECT
     ID,
     [Group],
     Flag,
     CASE 
          WHEN Flag = 'N' THEN 0
     ELSE
          ASCII([Group])-ASCII('A')+1
     END Rank
FROM
     #test
ORDER BY
     ID

答案 1 :(得分:1)

这是MySQL响应......

我真的不明白你所追求的是什么,但这里有一些东西需要实验......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,my_group    CHAR(1) NOT NULL
,flag CHAR(1) NOT NULL
);

INSERT INTO my_table VALUES
( 1,'A','Y'),
( 2,'A','Y'),
( 3,'A','Y'),
( 4,'A','Y'),
( 5,'A','N'),
( 6,'A','N'),
( 7,'A','N'),
( 8,'B','N'),
( 9,'B','Y'),
(10,'B','Y'),
(11,'B','Y'),
(12,'B','N'),
(13,'B','Y'),
(14,'B','Y');

SELECT id
     , my_group
     , flag
     , CASE WHEN flag = 'N' THEN 0 ELSE CEILING(i/2) END rank
  FROM 
     ( SELECT x.*
            , CASE WHEN flag <> @prev THEN @i:=@i+1 ELSE @i:=@i END + 1 i
            , @prev:=flag
         FROM my_table x
            , (SELECT @i:=0,@prev:=null) vars
        ORDER
           BY id
     ) a;

+----+----------+------+------+
| id | my_group | flag | rank |
+----+----------+------+------+
|  1 | A        | Y    |    1 |
|  2 | A        | Y    |    1 |
|  3 | A        | Y    |    1 |
|  4 | A        | Y    |    1 |
|  5 | A        | N    |    0 |
|  6 | A        | N    |    0 |
|  7 | A        | N    |    0 |
|  8 | B        | N    |    0 |
|  9 | B        | Y    |    2 |
| 10 | B        | Y    |    2 |
| 11 | B        | Y    |    2 |
| 12 | B        | N    |    0 |
| 13 | B        | Y    |    3 |
| 14 | B        | Y    |    3 |
+----+----------+------+------+

答案 2 :(得分:1)

以下是使用Tabibitosan在Oracle中执行此操作的一种方法:

with test as (select 1 id, 'A' groupp,'Y' flag from dual union all
              select 2, 'A', 'Y' from dual union all
              select 3, 'A', 'Y' from dual union all
              select 4, 'A', 'Y' from dual union all
              select 5, 'A', 'N' from dual union all
              select 6, 'A', 'N' from dual union all
              select 7, 'A', 'N' from dual union all
              select 8, 'B', 'N' from dual union all
              select 9, 'B', 'Y' from dual union all
              select 10, 'B', 'Y' from dual union all
              select 11, 'B', 'Y' from dual union all
              select 12, 'B', 'N' from dual union all
              select 13, 'B', 'Y' from dual union all
              select 14, 'B', 'Y' from dual)

select id,
       groupp,
       flag,
       grp,
       grp_id,
       case when flag = 'Y' then
                 dense_rank() over (partition by flag order by grp_id)
            else 0
       end rnk
from   (select id,
               groupp,
               flag,
               grp,
               min(case when flag = 'Y' then id end) over (partition by groupp, grp, flag) grp_id
        from   (select id,
                       groupp,
                       flag,
                       row_number() over (partition by groupp order by id)
                         - row_number() over (partition by groupp, flag order by id) grp
                from   test))
order by id;

首先,我们通过查找id顺序中groupp列的每个值的行号与idpp中的groupp和flag值的row_number来识别每组连续标志。如果存在差距,差异就会跳跃 - 这就是tabibitosan。

一旦你确定了这些群组,那就是分配等级号码的问题。由于我们在整个标志上分配排名(即按每个groupp值进行分区),我们需要弄清楚如何排序排名。要做到这一点,我只是找到每个最低的id(groupp,flag,grp)。

然后我们可以相应地分配等级,确保将'N'标志行设置为0。