2011-04-19 3 views
3

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

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

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 для поля с кратным?

ответ

0

Я думаю, вам нужен подзапрос для столбца 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 
+0

-1 Это непроверенный SQL. Ключевое слово END отсутствует, и если вы добавите это, оператор все равно будет терпеть неудачу с «ORA-01427: подзапрос однострочных строк возвращает более одной строки» –

7

Это более полезно размещать создать таблицу и вставить заявления вместо 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 смотреть через результирующий набор, чтобы увидеть, если КОЛА то же самое для следующего ряда (после заказа его ..) как ..

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 

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

+0

Спасибо, они оба очень полезны. В будущем я буду публиковать отчеты о создании/вставке. Кстати, я на самом деле набрал данные вручную. – Shereif

1
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 приблизительно равен первому запросу Rajesh. Таким образом, вы можете выбрать тот, с которым вам удобнее.

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

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

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

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; 

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

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

  • Нет связанных вопросов^_^