我有这些表格和数据:
CREATE TABLE a (
id NUMBER(3) NOT NULL
);
ALTER TABLE a ADD CONSTRAINT a_pk PRIMARY KEY ( id );
CREATE TABLE b (
id NUMBER(6) NOT NULL,
year NUMBER(4) NOT NULL,
a_id NUMBER(3) NOT NULL
);
ALTER TABLE b ADD CONSTRAINT b_pk PRIMARY KEY ( id );
CREATE TABLE c (
id NUMBER(9) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
a_id NUMBER(3) NOT NULL
);
ALTER TABLE c ADD CONSTRAINT c_pk PRIMARY KEY ( id );
ALTER TABLE b
ADD CONSTRAINT b_a_fk FOREIGN KEY ( a_id )
REFERENCES a ( id );
ALTER TABLE c
ADD CONSTRAINT c_a_fk FOREIGN KEY ( a_id )
REFERENCES a ( id );
Insert into A (ID) values ('1');
Insert into A (ID) values ('2');
Insert into A (ID) values ('3');
Insert into B (ID,YEAR,A_ID) values ('1','2017','1');
Insert into B (ID,YEAR,A_ID) values ('2','2017','2');
Insert into B (ID,YEAR,A_ID) values ('3','2013','3');
Insert into B (ID,YEAR,A_ID) values ('4','2014','3');
Insert into B (ID,YEAR,A_ID) values ('5','2017','3');
Insert into B (ID,YEAR,A_ID) values ('6','2013','1');
Insert into C (ID,START_DATE,END_DATE,A_ID) values ('1',to_date('01/01/13','DD/MM/RR'),to_date('01/01/14','DD/MM/RR'),'3');
Insert into C (ID,START_DATE,END_DATE,A_ID) values ('2',to_date('01/06/17','DD/MM/RR'),to_date('01/01/18','DD/MM/RR'),'3');
Insert into C (ID,START_DATE,END_DATE,A_ID) values ('3',to_date('01/01/14','DD/MM/RR'),to_date('01/06/14','DD/MM/RR'),'3');
Insert into C (ID,START_DATE,END_DATE,A_ID) values ('4',to_date('01/01/17','DD/MM/RR'),to_date('01/10/17','DD/MM/RR'),'1');
Insert into C (ID,START_DATE,END_DATE,A_ID) values ('5',to_date('01/04/13','DD/MM/RR'),to_date('01/10/13','DD/MM/RR'),'1');
Insert into C (ID,START_DATE,END_DATE,A_ID) values ('6',to_date('01/01/17','DD/MM/RR'),to_date('01/06/18','DD/MM/RR'),'2');
我需要每个B:B.id,A.id和C.id,其中C是第一个最早的start_date行,其中B.year位于C.start_date和C.end_date之间,如下所示:
BID AID CID
1 1 4
2 2 6
3 3 1
4 3 3
5 3 2
6 1 5
请帮助我找到答案或在哪里找到相关信息。
我知道嵌套选择并不能识别外面的表A,但我不知道如何为此制作一个有效的解决方案,或者我错过了一些非常简单的东西;我不知道。我希望你能帮助我。
在社区的帮助下我有这样的事情:
select B.id BID, A.id AID, C.id CID
from B
join A on B.A_id = A.id
join C
on C.A_id = A.id
where B.year between extract (year from C.start_date) and extract(year from C.end_date)
order by B.id ASC , c.start_date asc;
它返回了:
BID AID CID
1 1 4
2 2 6
3 3 1
4 3 1
4 3 3
5 3 2
6 1 5
但真正的答案是:
select bid, aid, cid
from
(select B.id bid, A.id aid, C.id cid,
row_number() over (partition by b.id order by c.start_date) rn
from B
join A on B.A_id = A.id
join c on C.A_id = A.id
and B.year between extract(year from c.start_date)
and extract(year from c.end_date))
where rn = 1;
返回我正在搜索的内容。
感谢所有人,尤其是Ponder Stibbons,这让我有了这样做的方法。
答案 0 :(得分:0)
您的DDL和查询存在太多问题。
避免使用oracle保留关键字作为列名。 end
作为列名的那个永远不会运行。
year NUMBER(4) NOT NULL,
start DATE NOT NULL,
end DATE NOT NULL,
而是使用类似year_t,start_t, end_t
的东西或有意义的东西。
我想用B.id,A.id和C.id做一个选择,其中C是第一个 B.year位于C.start和C.end之间的行,每个B。
您不能使用and rownum < 1
执行此操作。实际上rownum < 1
永远不会返回任何行。
您使用的列名也是错误的。例如:您在b.start
中没有使用order by
。
因此,考虑到这些更改,此查询将起作用。
select B.id, A.id, C.id
from B
join A on B.A_id = A.id
join C
on C.A_id = A.id
where B.year_t between to_number(to_char(C.start_t, 'YYYY')) and to_number(to_char(C.end_t, 'YYYY'))
order by c.start_t,B.id ASC ;
但是,它不会给你
B.year位于C.start和C.end之间的第一行,每一行 B
使用数据澄清您在问题中究竟需要哪些样本记录。然后我会尝试回答。
答案 1 :(得分:0)
构建join
,为每个id
编号行并只占第一行:
select bid, aid, cid
from (select B.id bid, A.id aid, C.id cid,
row_number() over (partition by c.a_id order by b.year) rn
from B
join A on B.A_id = A.id
join c on C.A_id = A.id
and B.year between extract(year from c.start_date)
and extract(year from c.end_date))
where rn = 1;
测试:
create table a (id number(3));
create table b (id number(6), year number(4), a_id number(3));
create table c (id number(9), start_date date, end_date date, a_id number(3));
insert into a values (1);
insert into a values (2);
insert into b values (1, 1901, 1);
insert into b values (2, 1905, 1);
insert into b values (3, 1903, 1);
insert into b values (4, 1902, 2);
insert into c values (1, date '1902-01-01', date '1912-07-17', 1);
insert into c values (2, date '1900-02-18', date '1910-06-08', 2);
结果:
BID AID CID
------- ---- ----------
3 1 1
4 2 2