Декартово / несколько записей на основе значения столбца - PullRequest
0 голосов
/ 06 ноября 2019

Есть две таблицы, назовем их PERSONS и PGROUP

create table persons(
id number(20),
name varchar2(30),
group_id number(30),
cnt number(2)
);

create table pgroup(
id number(20),
amount number(20));

insert into persons values(1,'name1',1,1);
insert into persons values(2,'name2',1,1 );
insert into persons values(3,'name3',1,1 );
insert into persons values(4,'name4',1,3 );
insert into persons values(5,'name5',null,5 );
insert into persons values(6,'name6',null,6 );
insert into persons values(7,'name7',null,7 );
insert into persons values(8,'name8',null,8 );
insert into persons values(9,'name9',null,9 );

insert into pgroup values(1,20000);
insert into pgroup values(2,12345);

Запись в таблице person может иметь ссылку на pgroup (persons.group_id = pgroup.id), но иногда нет никаких ключей. В этом сценарии (persons.group_id is null) этот человек «принадлежит» к каждой группе, поэтому я должен распространять («декартово») их через эти две группы.

С этим я могу справиться - один выбор для подключения этихзаписи, в которых есть ключи и союз с декартовой. Но я не могу понять, как их дублировать на основе столбца persons.cnt.

FE:

персона 'name9' имеет cnt = 9:

  • Мне нужно поместить 9 записей о нем, в 2 группы,

  • 9 записей в 1 группе должны иметь amt = 20000

  • еще 9 записей в группе 2 должны иметь amt = 12345;

, поэтому 1-й вопрос - возможно ли такое дублирование в SQL? 2-й - Все ли случаи, которые я здесь описываю, могут быть выполнены в ОДНОМ ЗАПРОСЕ (избегать объединения)?

1 Ответ

0 голосов
/ 06 ноября 2019

Я думаю, что следующий запрос выполняет эту работу:

-- Here is your sample data:
WITH persons (id, name, group_id, cnt) as 
   (select 1,'name1',1,1    from dual union all
    select 2,'name2',1,1    from dual union all
    select 3,'name3',1,1    from dual union all
    select 4,'name4',1,3    from dual union all
    select 5,'name5',null,5 from dual union all
    select 6,'name6',null,6 from dual union all
    select 7,'name7',null,7 from dual union all
    select 8,'name8',null,8 from dual union all
    select 9,'name9',null,9 from dual)
   , pgroup (id,amount) as
   (select 1,20000 from dual union all
    select 2,12345 from dual)
-- As cnt is number(2) it's < 100, the following query get's all number between 1 and 99
   , cnt as (select level cnt from dual connect by level < 100) 
SELECT p.id
     , p.name
     , g.id group_id 
     , c.cnt
     , g.amount
  FROM persons p
  JOIN cnt c
    ON c.cnt <= p.cnt -- Get the duplicate records
  join pgroup g
    ON g.id = p.group_id
    OR p.group_id is NULL -- Cartesian product if group_id is null

Столбцы g.id и c.cnt предназначены только для того, чтобы показать, что правильное количество дубликатов и декартово произведение работают, вы можетевместо этого нужно выбрать соответствующие значения таблицы persons.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...