Получить количество записей - Oracle - PullRequest
0 голосов
/ 05 марта 2020

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

Table A
Column 1   Column 2
121        XX
123        XX
124        A0
125        A2
126        XX

Table B
Column 1
A0
A1
A2
A3

Table C
Column 1 Column 2
121        A0
122        A1
123        A0
124        A0
125        A2
126        A3

Из них мне нужно подсчитать результат следующим образом:

Column 1     Column 2
XX,A0        2
XX,A1        0        
XX,A2        0
XX,A3        1
A0,A0        1
A1,A1        0
A2,A2        1
A3,A3        0

Здесь у меня 121 и 123 с XX в таблице A и такими же 121,123 в таблица C с A0, поэтому count должно быть 2. Аналогичным образом 124 имеют A0 в таблице A и A0 в таблице C, поэтому count должен иметь значение 1, и если ни одна запись не соответствует ни одному столбцу 2, он должен иметь 0.

Я пытался с помощью нижеуказанного запроса, он не возвращается, как ожидалось,

select b.column2 ||','|| c.column2 column , count(a.column1) count
          from table A a
          join table c c
           on a.column1=c.column1       
          join table b b
            on b.column1=c.column2
        group by b.column2 ||','|| c.column2
        order by b.column2 ||','|| c.column2

Ответы [ 3 ]

0 голосов
/ 05 марта 2020

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

create table tablea(id int, name varchar2(10));

create table tableb(name varchar2(10));

create table tablec(id int, name varchar2(10));

insert into tablea
select 121,'XX' from dual union all
select 123,'XX' from dual union all
select 124,'A0' from dual union all
select 125,'A2' from dual union all
select 126,'XX' from dual 

insert into tableb
select 'A0' from dual union all
select 'A1' from dual union all
select 'A2' from dual union all
select 'A3' from dual 

insert into tablec
select 121,'A0' from dual union all
select 122,'A1' from dual union all
select 123,'A0' from dual union all
select 124,'A0' from dual union all
select 125,'A2' from dual union all 
select 126,'A3' from dual 

--Gets all possible combination of tablea and tableb
select distinct a.name as a_name,b.name as b_name
       from tablea a
       join tableb b
         on 1=1

Затем вы могли бы группировать поля этих комбинаций следующим образом:

with data
 as (select distinct a.name as a_name,b.name as b_name
       from tablea a
       join tableb b
         on 1=1
     )  
    ,tablec_data
     as (select c.name c_name,a.name a_name
           from tablec c
           join tablea a
             on c.id=a.id
       )
select max(m.a_name||','||m.b_name) as val_name,count(n.c_name) as cnt
  from data m
left join tablec_data n
    on m.a_name=n.a_name
    and m.b_name=n.c_name
group by m.a_name,m.b_name    
order by m.a_name desc,m.b_name

Вот ссылка на БД-скрипта

https://dbfiddle.uk/?rdbms=oracle_18&fiddle=9e573822ecc1087e5871c80b586d1116

+----------+-----+
| VAL_NAME | CNT |
+----------+-----+
| XX,A0    |   2 |
| XX,A1    |   0 |
| XX,A2    |   0 |
| XX,A3    |   1 |
| A2,A0    |   0 |
| A2,A1    |   0 |
| A2,A2    |   1 |
| A2,A3    |   0 |
| A0,A0    |   1 |
| A0,A1    |   0 |
| A0,A2    |   0 |
| A0,A3    |   0 |
+----------+-----+
0 голосов
/ 05 марта 2020

Сначала подготовьте ключевые столбцы, используйте простое объединение. Затем используйте это keys для создания соединения. Left join используется потому, что нам тоже нужны нули:

with keys as (select 'XX' ka, column1 kb from b union all select column1, column1 from b)
select ka, kb, sum(case when c.column2 is not null then 1 else 0 end) cnt
  from keys
  left join a on ka = a.column2
  left join c on kb = c.column2 and a.column1 = c.column1
  group by ka, kb
  order by ka, kb

Демоверсия dbfiddle

0 голосов
/ 05 марта 2020

Table A следует использовать вместо Table B для объединения значений. Таблица B не имеет столбца Colunn2.

. Кроме того, имя псевдонима Remember для a.column2 ||','|| c.column2 не должно быть column, поскольку это зарезервированное ключевое слово в oracle. Таким образом, вы можете использовать column2 или что-то еще.

РЕДАКТИРОВАТЬ: Следующее даст 0 количество для несопоставленных записей.

select t1.column2,
case when t2.count1 is not null then t2.count1 else t1.count1 end as count1 
from (
(select distinct a.column2||','||b.column1 as column2,
 0 as count1 from tableA a join tableB b on  a.column2='XX'
union 
select distinct c.column2||','||b.column1 as column2,
 0 as count1 from tableC c join tableB b on c.column2=b.column1
)t1
left join 
(select a.Column2 ||','|| c.Column2 as column2, 
  count(*) count1 from TableA a join TableC c on a.column1=c.column1 
  join TableB B on b.column1=c.column2 group by a.column2 ||','|| c.column2 
)t2
on t1.column2=t2.column2
)
order by 
t1.column2

Вывод:

A0,A0   1
A1,A1   0
A2,A2   1
A3,A3   0
XX,A0   2
XX,A1   0
XX,A2   0
XX,A3   1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...