2016-06-22 6 views
1

У меня есть данные в этом формате.Ввод того же ранга в схожие значения

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 

Может кто-нибудь скажет мне, как получить этот результат?

резюме, почему конкретный порядок выше результата:
Я хочу взять максимум значений для каждой группы, где флаг = «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' 
+1

Как вы приказывая эти результаты? Если у вас есть какой-то столбец «ID», который вы можете заказать, нет никакой гарантии, что ваш заказ будет таким же. SQL представляет * неупорядоченные * наборы данных. – Siyual

+0

Без чего-либо заказать, у вас возникнет проблема с 'B Y 3' –

+2

Невозможно установить шаблон в результате. Можете ли вы добавить какое-то описание к выходу? –

ответ

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 
+0

Спасибо за ваш ответ. Это было действительно полезно! – Beta

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:[email protected]+1 ELSE @i:[email protected] 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 | 
+----+----------+------+------+ 
+0

Спасибо за ваш ответ. Но я правильно ответил на вопрос Джонни. – Beta

1

Вот один из способов вы можете сделать это в Oracle, используя Tabibitosan:

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; 

во-первых, мы определяем каждый набор consecu чтобы найти разницу номера строки для каждого значения столбца groupp в порядке id и row_number значений groupp и flag в порядке id. Там, где есть пробелы, разница будет прыгать - это табибитозан.

Как только вы определили группы, тогда вам необходимо присвоить номера рангов. Поскольку мы назначаем ряды по всему флагу (то есть не разбиение по каждому значению groupp), нам нужно выяснить, как упорядочить рейтинг. Для этого я просто нашел наименьший идентификатор для каждого (groupp, flag, grp).

Тогда мы можем присвоить ранг соответственно, убедившись, чтобы установить флаг строки «N» 0.

+0

Спасибо за прекрасный ответ! Это была красота и точно выполнила мое требование. И вы также очень четко объясняете ответ. Я уже отметил, что Джонни ответил правильно. Но я прошу проголосовать за другие ваши ответы. Большое спасибо! – Beta

Смежные вопросы