Выберите строки, в которых ColA = ColB, а также добавьте новый столбец, в котором будет указано, повторяются ли исходные данные в ColA. - PullRequest
3 голосов
/ 20 апреля 2011

Я пытаюсь выяснить, как сделать запрос к таблице (таблица на самом деле является набором результатов, поэтому это будет подзапрос), сгруппировать ее по ColA=ColB (см. Ниже) и создать вычисляемое поле все в одном шаг.

Итак, если мои тестовые данные выглядят как

ColA    ColB    ColC 
1       1       aaa 
1       2       bbbb    
1       3       cccc    
2       2       dddd    
3       3       eeee    
3       4       ffff    
3       5       gggg    
3       6       hhhh    
4       4       iiii    
5       5       jjjj    
6       6       kkkk    
6       7       llll    
6       8       mmmm    

Я хотел бы получить только те строки, в которых ColA=ColB, а также добавить новый столбец, в котором указано, были ли повторены исходные данные в ColA. Увидеть ниже.

ColA   ColB    ColC    multiples
1      1       aaaa    yes
2       2       dddd    no
3       3       eeee    yes
4       4       iiii    no
5       5       jjjj    no
6       6       kkkk    yes

Может кто-нибудь помочь мне с синтаксисом? Я играл с Group By и SubSelects безрезультатно. Нужно ли использовать оператор case для поля кратных?

Ответы [ 4 ]

7 голосов
/ 20 апреля 2011

Более полезно публиковать операторы создания таблицы и вставки вместо таблицы Desc и выбирать * из table_name;http://tkyte.blogspot.com/2005/06/how-to-ask-questions.html

create table test_repeat(
   cola number,
   colb number,
   colc varchar2(20)
   );

insert into test_repeat values (1,1,'aaa'); 
insert into test_repeat values (1,2,'bbbb');    
insert into test_repeat values (1,3,'cccc');    
insert into test_repeat values (2,2,'dddd');    
insert into test_repeat values (3,3,'eeee'); 
insert into test_repeat values (3,4,'ffff');    
insert into test_repeat values (3,5,'gggg');    
insert into test_repeat values (3,6,'hhhh');    
insert into test_repeat values (4,4,'iiii');    
insert into test_repeat values (5,5,'jjjj');    
insert into test_repeat values (6,6,'kkkk');    
insert into test_repeat values (6,7,'llll');    
insert into test_repeat values (6,8,'mmmm');
commit;

1.Вы можете использовать аналитическую функцию Oracle Lead , чтобы просмотреть ваш результирующий набор, чтобы увидеть, совпадает ли colA для следующей строки (после упорядочивания ..) как ..

select * from
(select colA, colb,
       (case when colA = (lead(cola) over 
                          (partition by colA order by cola, colb))
            then 'Yes'
            else 'No'
       end) multiples,
       colc
  from test_repeat)
  where colA = colb
/

      COLA       COLB MUL COLC
---------- ---------- --- --------------------
         1          1 Yes aaa
         2          2 No  dddd
         3          3 Yes eeee
         4          4 No  iiii
         5          5 No  jjjj
         6          6 Yes kkkk

2.Или вы можете получить счетчик для каждого значения COLA и сравнить его, чтобы увидеть, есть ли дубликаты ...

select a.colA, a.colb, a.colc,
       (case when (select count(*) from test_repeat t where t.cola = a.colA) > 1
            then 'Yes'
            else 'No'
       end) Repeat
  from test_repeat a
  where colA = colB
/

      COLA       COLB COLC                 REP
---------- ---------- -------------------- ---
         1          1 aaa                  Yes
         2          2 dddd                 No
         3          3 eeee                 Yes
         4          4 iiii                 No
         5          5 jjjj                 No
         6          6 kkkk                 Yes

Они оба одинаково просты, но Я бы предложил подход аналитической функции какЯ обнаружил, что он в целом быстрее для всех запросов , с которыми я работал в прошлом.

1 голос
/ 20 апреля 2011
SQL> select *
  2    from test_repeat
  3   order by cola
  4  /

      COLA       COLB COLC
---------- ---------- --------------------
         1          2 bbbb
         1          1 aaa
         1          3 cccc
         2          2 dddd
         3          4 ffff
         3          3 eeee
         3          5 gggg
         3          6 hhhh
         4          4 iiii
         5          5 jjjj
         6          6 kkkk
         6          7 llll
         6          8 mmmm
         7          9 nnnn

14 rows selected.

SQL> select cola "ColA"
  2       , max(decode(colb,cola,colb)) "ColB"
  3       , max(decode(colb,cola,colc)) "ColC"
  4       , case count(*) when 1 then 'no' else 'yes' end "multiples"
  5    from test_repeat
  6   group by cola
  7  having cola = max(decode(colb,cola,colb))
  8   order by cola
  9  /

      ColA       ColB ColC                 mul
---------- ---------- -------------------- ---
         1          1 aaa                  yes
         2          2 dddd                 no
         3          3 eeee                 yes
         4          4 iiii                 no
         5          5 jjjj                 no
         6          6 kkkk                 yes

6 rows selected.

Производительность, этот SQL примерно равен первому запросу Раджеша.Так что вы можете выбрать тот, который вам удобнее.

SQL> set autotrace on
SQL> select * from
  2  (select colA, colb,
  3         (case when colA = (lead(cola) over
  4                            (partition by colA order by cola, colb))
  5              then 'Yes'
  6              else 'No'
  7         end) multiples,
  8         colc
  9    from test_repeat)
 10    where colA = colb
 11  /

      COLA       COLB MUL COLC
---------- ---------- --- --------------------
         1          1 Yes aaa
         2          2 No  dddd
         3          3 Yes eeee
         4          4 No  iiii
         5          5 No  jjjj
         6          6 Yes kkkk

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1491815685

-----------------------------------------------------------------------------------
| Id  | Operation           | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |    14 |   574 |     4  (25)| 00:00:01 |
|*  1 |  VIEW               |             |    14 |   574 |     4  (25)| 00:00:01 |
|   2 |   WINDOW SORT       |             |    14 |   532 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| TEST_REPEAT |    14 |   532 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("COLA"="COLB")

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
         15  consistent gets
          0  physical reads
          0  redo size
        421  bytes sent via SQL*Net to client
        238  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          6  rows processed

SQL> /

      COLA       COLB MUL COLC
---------- ---------- --- --------------------
         1          1 Yes aaa
         2          2 No  dddd
         3          3 Yes eeee
         4          4 No  iiii
         5          5 No  jjjj
         6          6 Yes kkkk

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1491815685

-----------------------------------------------------------------------------------
| Id  | Operation           | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |    14 |   574 |     4  (25)| 00:00:01 |
|*  1 |  VIEW               |             |    14 |   574 |     4  (25)| 00:00:01 |
|   2 |   WINDOW SORT       |             |    14 |   532 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| TEST_REPEAT |    14 |   532 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("COLA"="COLB")

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        421  bytes sent via SQL*Net to client
        238  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          6  rows processed

SQL> select cola "ColA"
  2       , max(decode(colb,cola,colb)) "ColB"
  3       , max(decode(colb,cola,colc)) "ColC"
  4       , case count(*) when 1 then 'no' else 'yes' end "multiples"
  5    from test_repeat
  6   group by cola
  7  having cola = max(decode(colb,cola,colb))
  8   order by cola
  9  /

      ColA       ColB ColC                 mul
---------- ---------- -------------------- ---
         1          1 aaa                  yes
         2          2 dddd                 no
         3          3 eeee                 yes
         4          4 iiii                 no
         5          5 jjjj                 no
         6          6 kkkk                 yes

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3021378319

-----------------------------------------------------------------------------------
| Id  | Operation           | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |    14 |   532 |     4  (25)| 00:00:01 |
|*  1 |  FILTER             |             |       |       |            |          |
|   2 |   SORT GROUP BY     |             |    14 |   532 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| TEST_REPEAT |    14 |   532 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("COLA"=MAX(DECODE("COLB","COLA","COLB")))

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        421  bytes sent via SQL*Net to client
        238  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          6  rows processed

SQL> /

      ColA       ColB ColC                 mul
---------- ---------- -------------------- ---
         1          1 aaa                  yes
         2          2 dddd                 no
         3          3 eeee                 yes
         4          4 iiii                 no
         5          5 jjjj                 no
         6          6 kkkk                 yes

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3021378319

-----------------------------------------------------------------------------------
| Id  | Operation           | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |             |    14 |   532 |     4  (25)| 00:00:01 |
|*  1 |  FILTER             |             |       |       |            |          |
|   2 |   SORT GROUP BY     |             |    14 |   532 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| TEST_REPEAT |    14 |   532 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("COLA"=MAX(DECODE("COLB","COLA","COLB")))

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        420  bytes sent via SQL*Net to client
        238  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          6  rows processed

SQL> set autotrace off

С уважением,
Роб.

0 голосов
/ 21 апреля 2011

Я не знал о ведущей функции, очень приятно. Роб и Раджеш, спасибо за ответы, я думаю, что смог частично ответить на свой вопрос, используя два подзапроса и внешнее объединение.

Я предполагаю, что мой запрос не так эффективен, как остальные, но мне интересно, могут ли люди прокомментировать этот запрос. Это всегда будет работать? Можно ли его настроить, чтобы сделать его более эффективным? Для множителей по-прежнему необходимо указывать «да» или «нет», прямо сейчас для нуля множественное число или ноль.

SELECT BB.ColA, ColB, ColC, AA.CNT 
FROM
(SELECT ColA, count(*) as CNT FROM TMPY where ColA<>ColB Group by ColA)  AA, 
(SELECT ColA, ColB, ColC FROM TMPY WHERE COLA=COLB ) BB 
WHERE
AA.COLa(+)=BB.COLB order by bb.ColA;

Еще раз спасибо!

0 голосов
/ 20 апреля 2011

Я думаю, вам нужен отбор для столбца multiples. Группировка не требуется. Напишите что-то вроде:

select ColA, ColB, ColC, 
       (CASE
        WHEN (select b.ColA from thistable b where b.ColA = a.ColA) > 1 THEN 'yes'
        ELSE 'no'
        END)
from thistable a
where ColA = ColB
...