SQL Display every class - sql

Can someone assist me with my Oracle SQL joins, something is missing.
The select statement below lists every Student and the Class Date but I want to show every Class for each Student, even if the Student took the Class or not.
Kim, Brandy and Trina, Brandy should have every class name listed with no Class Date since they have not took any class yet.
Green, Robert took 3 Classes and did not take 2 Classes, the 2 Classes should be listed also with no Class Date since he did not take them.
The insert statements and create tables are listed. Let me know if you have any questions. Thanks
SELECT VW.STUDENT_NAME,
VW.EMPLE_NO,
CN.PK_CLASS_NAME_ID,
CN.CLASS_NAME,
DP.CLASS_DATE
FROM EMPLOYEE_NAME VW
LEFT JOIN DEMO_PRODUCT_INFO_NEW DP ON DP.FK_CO_EMPL_ID = VW.EMPLE_NO
LEFT JOIN TBL_CLASS_NAME_NEW CN
ON CN.PK_CLASS_NAME_ID = DP.FK_CLASS_NAME_ID
ORDER BY STUDENT_NAME ASC;
CREATE TABLE TBL_CLASS_NAME_NEW
(
PK_CLASS_NAME_ID INTEGER,
CLASS_NAME VARCHAR2(75 BYTE)
);
Insert into TBL_CLASS_NAME_NEW
(PK_CLASS_NAME_ID, CLASS_NAME)
Values
(1, 'CPR');
Insert into TBL_CLASS_NAME_NEW
(PK_CLASS_NAME_ID, CLASS_NAME)
Values
(3, 'ETHICS');
Insert into TBL_CLASS_NAME_NEW
(PK_CLASS_NAME_ID, CLASS_NAME)
Values
(4, 'HARRASEMENT');
Insert into TBL_CLASS_NAME_NEW
(PK_CLASS_NAME_ID, CLASS_NAME)
Values
(5, 'DEFENSIVE TEST');
Insert into TBL_CLASS_NAME_NEW
(PK_CLASS_NAME_ID, CLASS_NAME)
Values
(2, 'RANGE');
COMMIT;
CREATE TABLE DEMO_PRODUCT_INFO_NEW
(
PRODUCT_ID NUMBER NOT NULL,
FK_CO_EMPL_ID NUMBER,
FK_CLASS_NAME_ID NUMBER,
CLASS_DATE DATE
);
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(4, 4, 1, TO_DATE('7/18/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(22, 4, 1, TO_DATE('7/25/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(18, 4, 4, TO_DATE('7/18/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(21, 4, 3, TO_DATE('7/4/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(32, 22, 2, TO_DATE('8/15/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(34, 22, 1, TO_DATE('8/29/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(35, 22, 1, TO_DATE('7/4/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(46, 18, 4, TO_DATE('7/4/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(43, 18, 5, TO_DATE('7/11/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(45, 4, 2, TO_DATE('7/4/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(48, 4, 5, TO_DATE('7/11/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(51, 22, 3, TO_DATE('7/4/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(52, 18, 3, TO_DATE('7/18/2021', 'MM/DD/YYYY'));
Insert into DEMO_PRODUCT_INFO_NEW
(PRODUCT_ID, FK_CO_EMPL_ID, FK_CLASS_NAME_ID, CLASS_DATE)
Values
(5, 4, 2, TO_DATE('7/25/2021', 'MM/DD/YYYY'));
COMMIT;
CREATE TABLE EMPLOYEE_NAME
(
EMPLE_NO INTEGER,
STUDENT_NAME VARCHAR2 (100 BYTE),
LAST_NAME VARCHAR2 (40 BYTE),
FIRST_NAME VARCHAR2 (40 BYTE)
);
Insert into EMPLOYEE_NAME
(EMPLE_NO, STUDENT_NAME, LAST_NAME, FIRST_NAME)
Values
(4, 'WENDY, FRANK', 'FRANK', 'WENDY');
Insert into EMPLOYEE_NAME
(EMPLE_NO, STUDENT_NAME, LAST_NAME, FIRST_NAME)
Values
(22, 'JOHN, JAMES', 'JAMES', 'JOHN');
Insert into EMPLOYEE_NAME
(EMPLE_NO, STUDENT_NAME, LAST_NAME, FIRST_NAME)
Values
(18, 'GREEN, ROBERT', 'ROBERT', 'GREEN');
Insert into EMPLOYEE_NAME
(EMPLE_NO, STUDENT_NAME, LAST_NAME, FIRST_NAME)
Values
(21, 'KIM, BRANDY', 'BRANDY', 'KIM');
Insert into EMPLOYEE_NAME
(EMPLE_NO, STUDENT_NAME, LAST_NAME, FIRST_NAME)
Values
(32, 'TRINA, JAMIE', 'JAMIE', 'TRINA');

This is how the following query works
T1: Lists all the courses and students that the student can choose.
T2: Lists all the courses and students that the student has chosen
Then T1 goes to T2 LEFT JOIN with equal number of PK_CLASS_NAME_ID and EMPLE_NO
SELECT
T1.STUDENT_NAME,
T1.EMPLE_NO,
T1.PK_CLASS_NAME_ID,
T1.CLASS_NAME,
T2.CLASS_DATE
FROM
(
SELECT VW.STUDENT_NAME,
VW.EMPLE_NO,
CN.PK_CLASS_NAME_ID,
CN.CLASS_NAME
FROM TBL_CLASS_NAME_NEW CN
JOIN EMPLOYEE_NAME VW
ON 1=1
GROUP BY VW.STUDENT_NAME,VW.EMPLE_NO, CN.PK_CLASS_NAME_ID, CN.CLASS_NAME
) T1
LEFT JOIN
(
SELECT VW.STUDENT_NAME,
VW.EMPLE_NO,
CN.PK_CLASS_NAME_ID,
CN.CLASS_NAME,
DP.CLASS_DATE
FROM TBL_CLASS_NAME_NEW CN
JOIN DEMO_PRODUCT_INFO_NEW DP
ON CN.PK_CLASS_NAME_ID = DP.FK_CLASS_NAME_ID
JOIN EMPLOYEE_NAME VW
ON DP.FK_CO_EMPL_ID = VW.EMPLE_NO
GROUP BY VW.STUDENT_NAME,VW.EMPLE_NO,CN.PK_CLASS_NAME_ID, CN.CLASS_NAME,DP.CLASS_DATE
) T2 ON T1.EMPLE_NO = T2.EMPLE_NO ANd T1.PK_CLASS_NAME_ID = T2.PK_CLASS_NAME_ID
I got the output in SQL, but it doesn't matter, it works in Oracle.

Related

While combining tables, how to make a column distinct when it has multiple entries?

I'm trying to display course numbers from table student_enrollment and student names from table students, based on a distinct last_name from table professors. For example, there is a professor named "Wilson" - I would like to only display the courses Wilson's teaching and the students that are enrolled in these classes.
What I have so far is the following, which displays the unique course numbers that each student is enrolled in but does not take into consideration of professors.last_name:
SELECT students.student_name, student_enrollment.course_no
FROM students, student_enrollment, teach
WHERE students.student_no=student_enrollment.student_no
AND student_enrollment.course_no=teach.course_no
GROUP BY student_name,student_enrollment.course_no
Please see the four queried tables (students, student_enrollment, teach, professors) below for more information:
create table students
(
student_no integer,
student_name varchar(20),
age integer
);
insert into students values (1, 'Harpreet', 19);
insert into students values (2, 'Doug', 18);
insert into students values (3, 'Abdul', 21);
insert into students values (4, 'Mohammad', 20);
insert into students values (5, 'Ralph', 19);
insert into students values (6, 'Prateek', 22);
insert into students values (7, 'Michael', 19);
insert into students values (8, 'Jack', 19);
insert into students values (9, 'Chin', 17);
insert into students values (10, '', 20);
create table courses
(
course_no varchar(5),
course_title varchar(20),
credits integer
);
insert into courses values ('CS110', 'Pre Calculus', 4);
insert into courses values ('CS180', 'Physics', 4);
insert into courses values ('CS107', 'Intro to Psychology', 3);
insert into courses values ('CS210', 'Art History', 3);
insert into courses values ('CS220', 'US History', 3);
create table student_enrollment
(
student_no integer,
course_no varchar(5)
);
insert into student_enrollment values (1, 'CS110');
insert into student_enrollment values (1, 'CS180');
insert into student_enrollment values (1, 'CS210');
insert into student_enrollment values (2, 'CS107');
insert into student_enrollment values (2, 'CS220');
insert into student_enrollment values (3, 'CS110');
insert into student_enrollment values (3, 'CS180');
insert into student_enrollment values (4, 'CS220');
insert into student_enrollment values (5, 'CS110');
insert into student_enrollment values (5, 'CS180');
insert into student_enrollment values (5, 'CS210');
insert into student_enrollment values (5, 'CS220');
insert into student_enrollment values (6, 'CS110');
insert into student_enrollment values (7, 'CS110');
insert into student_enrollment values (7, 'CS210');
create table professors
(
last_name varchar(20),
department varchar(12),
salary integer,
hire_date date
);
insert into professors values ('Chong', 'Science', 88000, '2006-04-18');
insert into professors values ('Brown', 'Math', 97000, '2002-08-22');
insert into professors values ('Jones', 'History', 67000, '2009-11-17');
insert into professors values ('Wilson', 'Astronomy', 110000, '2005-01-15');
insert into professors values ('Miller', 'Agriculture', 82000, '2008-05-08');
insert into professors values ('Williams', 'Law', 105000, '2001-06-05');
create table teach
(
last_name varchar(20),
course_no varchar(5)
);
insert into teach values ('Chong', 'CS180');
insert into teach values ('Brown', 'CS110');
insert into teach values ('Brown', 'CS180');
insert into teach values ('Jones', 'CS210');
insert into teach values ('Jones', 'CS220');
insert into teach values ('Wilson', 'CS110');
insert into teach values ('Wilson', 'CS180');
insert into teach values ('Williams', 'CS107');
Note that there may be multiple professors teaching the same course (and there are students enrolled in the same course more than once).
If anyone has a pointer as to what I am missing here, please let me know! I'm new to SQL and have tried a few ideas unsuccessfully.
A simple and quick way to organize the sql is to use sub clause.
select s.*, c.*
from student_enrollment se
inner join student s on se.student_no = s.student_no
inner join course c on se.course_no = c.course_no
where course_no in (select course_no from teach where last_name = 'Wilson')

Can I reference this table?

I am trying to show amount paid for each tutor sorted by month and then by tutor id. I have the first part correct and can sort by month but cannot sort by tutor id because it is from a different table.
Here is the script for my tables:
create table match_history
(match_id number(3),
tutor_id number(3),
student_id number(4),
start_date date,
end_date date,
constraint pk_match_history primary key (match_id),
constraint fk1_match_history foreign key (tutor_id) references tutor(tutor_id),
constraint fk2_match_history foreign key (student_id) references student(student_id));
create table tutor_report
(match_id number(3),
month date,
hours number(3),
lessons number(3),
constraint pk_tutor_report primary key (match_id, month),
constraint fk1_tutor_report foreign key (match_id) references match_history(match_id));
insert into tutor values (100, '05-JAN-2017', 'Active');
insert into tutor values (101, '05-JAN-2017', 'Temp Stop');
insert into tutor values (102, '05-JAN-2017', 'Dropped');
insert into tutor values (103, '22-MAY-2017', 'Active');
insert into tutor values (104, '22-MAY-2017', 'Active');
insert into tutor values (105, '22-MAY-2017', 'Temp Stop');
insert into tutor values (106, '22-MAY-2017', 'Active');
insert into student values (3000, 2.3);
insert into student values (3001, 5.6);
insert into student values (3002, 1.3);
insert into student values (3003, 3.3);
insert into student values (3004, 2.7);
insert into student values (3005, 4.8);
insert into student values (3006, 7.8);
insert into student values (3007, 1.5);
insert into match_history values (1, 100, 3000, '10-JAN-2017', null);
insert into match_history values (2, 101, 3001, '15-JAN-2017', '15-MAY-2017');
insert into match_history values (3, 102, 3002, '10-FEB-2017', '01-MAR-2017');
insert into match_history values (4, 106, 3003, '28-MAY-2017', null);
insert into match_history values (5, 103, 3004, '01-JUN-2017', '15-JUN-2017');
insert into match_history values (6, 104, 3005, '01-JUN-2017', '28-JUN-2017');
insert into match_history values (7, 104, 3006, '01-JUN-2017', null);
insert into tutor_report values (1, '01-JUN-2017', 8, 4);
insert into tutor_report values (4, '01-JUN-2017', 8, 6);
insert into tutor_report values (5, '01-JUN-2017', 4, 4);
insert into tutor_report values (4, '01-JUL-2017', 10, 5);
insert into tutor_report values (1, '01-JUL-2017', 4, 2);
This is what I have so far:
Select (hours * 10) as amount paid from tutor_report group by month, tutor_id
however obviously I cannot just say tutor_id at the end.
You can join match_history to get the tutor_id.
But your statement and the query don't match. If you want to sort use ORDER BY.
SELECT tr.hours * 10 amount_paid
FROM tutor_report tr
INNER JOIN match_history mh
ON mh.match_id = tr.match_id
ORDER BY tr.month,
mh.tutor_id;
If you want to aggregate, hours needs to be argument to some aggregation function. Maybe you're after the sum of hours?
SELECT sum(tr.hours) * 10 amount_paid
FROM tutor_report tr
INNER JOIN match_history mh
ON mh.match_id = tr.match_id
GROUP BY tr.month,
mh.tutor_id;
If you are grouping based on columns on two tables,you need to join them on the matching Id and then use group by
Select (hours * 10) as amount paid
from tutor_report a
join match_history b on a. match_id = b.match_id
group by month, tutor_id

Unknown column in where clause?

My code:
drop table if exists HSstudents;
create table HSstudents
(
HSsID int,
vNAAM text,
aNAAM text,
LT int,
GM float
);
insert into HSstudents values (1, 'Thomas', 'Jansen', 18, 7.0);
insert into HSstudents values (2, 'Jesse', 'Bakker', 19, 6.5);
insert into HSstudents values (3, 'Tom', 'Smit', 20, 7.1);
insert into HSstudents values (4, 'Jelle', 'Visser', 17, 9.6);
insert into HSstudents values (5, 'Sem', 'Dekker', 17, 8.1);
insert into HSstudents values (6, 'Anna', 'Peters', 18, 6.8);
insert into HSstudents values (7, 'Michelle', 'Hendriks', 19, 8.2);
insert into HSstudents values (8, 'Senna', 'Mulder', 20, 5.9);
insert into HSstudents values (9, 'Sven', 'Linden', 21, 6.0);
insert into HSstudents values (10, 'Ilse', 'Jacobs', 21, 7.5);
insert into HSstudents values (11, 'Harm', 'Schouten', 19, 7.0);
insert into HSstudents values (12, 'Emma', 'Dijkstra', 18, 8.1);
drop table if exists students;
create table students
(
sID int,
vNAAM text,
aNAAM text,
LT int
);
insert into students values (1, 'Thomas', 'Jansen', 18);
insert into students values (2, 'Jesse', 'Bakker', 19);
insert into students values (3, 'Tom', 'Smit', 20);
insert into students values (4, 'Jelle', 'Visser', 17);
insert into students values (5, 'Sem', 'Dekker', 17);
insert into students values (6, 'Anna', 'Peters', 18);
insert into students values (7, 'Michelle', 'Hendriks', 19);
insert into students values (8, 'Senna', 'Mulder', 20);
insert into students values (9, 'Sven', 'Linden', 21);
insert into students values (10, 'Ilse', 'Jacobs', 21);
insert into students values (11, 'Harm', 'Schouten', 19);
insert into students values (12, 'Emma', 'Dijkstra', 18);
drop table if exists applications;
create table applications
(
sID int,
aPROV text,
sPROV text,
taal text
);
insert into applications values (1, 'Overijssel', 'Drenthe', 'HTML');
insert into applications values (2, 'Gelderland', 'Overijssel', 'CSS');
insert into applications values (3, 'Groningen', 'Flevoland', 'CSS');
insert into applications values (4, 'Overijssel', 'Zuid-Holland', 'SQL');
insert into applications values (5, 'Noord-Holland', 'Drenthe', 'C#');
insert into applications values (6, 'Flevoland', 'Groningen', 'C#');
insert into applications values (7, 'Limburg', 'Groningen', 'JAVA');
insert into applications values (8, 'Limburg', 'Limburg', 'JAVASCRIPT');
insert into applications values (9, 'Drenthe', 'Noord-Brabant', 'CSS');
insert into applications values (10, 'Drenthe', 'Zeeland', 'Python');
insert into applications values (11, 'Zuid-Holland', 'Friesland', 'C++');
insert into applications values (12, 'Zeeland', 'Friesland', 'JAVA');
select
S.sID, S.vNAAM, S.aNAAM, S.LT, aPROV, sPROV, taal
from
HSstudents HS, students S, applications A
where
HSstudents.HSsID = students.sID
This results in an error
Code: 1054. Unknown column 'HSstudents.HSsID' in 'where clause'
How? Shouldn't it just work?
WHERE clause should follow the remane on the FROM clause:
where HS.HSsID = S.sID

Performing a subquery using values from a column in Oracle

I'm trying to create a calculated column in SQL. Basically I need to get a set of distinct dates and determine how many customers there are in the population on that particular date. The result should be something like:
Date______| Customers
2016-01-01 | 1
2016-01-01 | 2
2016-01-05 | 3
2016-02-09 | 4
etc.
I created a sample database & data (using MySQL as I don't have permission to create tables in our Oracle dbs) with the following script:
create database customer_example;
use customer_example;
create table customers (
customer_id int not null primary key,
customer_name varchar(255) not null,
term_date DATE);
create table employee (
employee_id int not null primary key,
employee_name varchar(255) not null);
create table cust_emp (
ce_id int not null AUTO_INCREMENT,
emp_id int not null,
cust_id int not null,
start_date date,
end_date date,
deleted_yn boolean,
primary key (emp_id, cust_id, ce_id),
foreign key (cust_id) references customers(customer_id),
foreign key (emp_id) references employee(employee_id));
insert into customers (customer_id, customer_name)
values (1, 'Bobby Tables'), (2, 'Grover Cleveland'), (3, 'Chester Arthur'), (4, 'Jan Bush'), (5, 'Emanuel Porter'), (6, 'Darren King'), (7, 'Casey Mcguire'), (8, 'Robin Simpson'), (9, 'Robin Tables'), (10, 'Mitchell Arnold');
insert into customers (customer_id, customer_name, term_date)
values (11, 'Terrell Graves', '2017-01-01'), (12, 'Richard Wagner', '2016-10-31'), (13, 'Glenn Saunders', '2016-11-19'), (14, 'Bruce Irvin', '2016-03-11'), (15, 'Glenn Perry','2016-06-06'), (16, 'Hazel Freeman', '2016-07-10'),
(17, 'Martin Freeman', '2016-02-11'), (18, 'Morgan Freeman', '2017-02-01'), (19, 'Dirk Drake', '2017-01-12'), (20, 'Fraud Fraud', '2016-12-31');
insert into employee (employee_id, employee_name)
values (1000, 'Cedrick French'), (1001, 'Jane Phillips'), (1002, 'Brian Green'), (1003, 'Shawn Brooks'), (1004, 'Clarence Thomas');
insert into cust_emp (emp_id, cust_id, start_date, end_date)
values (1000, 1, '2016-01-01', '2016-02-01'), (1000, 1, '2016-02-01', '2016-02-01'), (1000, 2,'2016-01-05', '2016-01-16'),(1000, 3,'2016-02-09', '2016-03-14'),(1000, 4,'2016-03-20', '2016-04-23'),
(1000, 5,'2016-01-01', '2016-01-16'),(1000, 6,'2016-01-01', '2016-01-16'),(1004, 7, '2016-01-14', '206-01-16'),
(1004, 8, '2016-01-13', '2016-01-16'),(1004, 9, '2016-01-05', '2016-01-16'), (1003, 12, '2016-04-21', '2016-11-30');
insert into cust_emp (emp_id, cust_id, start_date, deleted_yn)
values (1002, 11, '2016-04-10', TRUE),(1003, 10, '2016-01-16', FALSE), (1004, 12, '2016-04-20', TRUE), (1004, 12, '2016-04-19', FALSE), (1003, 13, '2016-06-06', TRUE), (1002, 14, '2016-06-10', TRUE),
(1004, 15, '2016-03-25', TRUE), (1004, 17, '2016-01-02', TRUE), (1004, 18, '2017-01-01', TRUE), (1004, 19, '2016-11-13', TRUE), (1004, 20, '2016-03-10', TRUE), (1004, 16, '2016-05-13', TRUE);
insert into cust_emp (emp_id, cust_id, start_date)
values (1002, 1, '2016-02-01'), (1004, 2, '2016-01-16'),(1003, 3, '2016-03-14'),(1002, 4, '2016-04-23'),(1004, 5, '2016-01-16'),(1002, 6, '2016-01-16'),(1004, 7, '2016-01-16'),
(1004, 8, '2016-01-16'),(1002, 9, '2016-01-16'), (1004, 10, '2016-01-16');
The following SQL works fine in MySQL but when I try it in Oracle, I get an 'invalid identifier' on 'dates':
select distinct(ce.start_date) as dates,
(select count(distinct(c.customer_id))
from customers c
inner join cust_emp ce on c.customer_id = ce.cust_id
where ce.start_date < dates
and (ce.end_date > dates or (ce.deleted_yn = false or ce.deleted_yn is null))
and (c.term_date > dates or c.term_date is null)
)
from cust_emp as ce;
It seems as though this is because the dates is too far in a subquery. I've tried a CTE as well, but that seems to have the same issue as it gave the same error. How can I re-write this so that I can assess how many customers were there for each date in Oracle?
Huh?
Isn't this what you want?
select ce.dates as dates, count(distinct c.customer_id)
from cust_emp ce join
customers c
on c.customer_id = ce.cust_id
where ce.start_date < ce.dates and
(ce.end_date > ce.dates or ce.deleted_yn = false or ce.deleted_yn is null) and
(c.term_date > ce.dates or c.term_date is null)
group by ce.dates
order by ce.dates;
I don't really understand the use of the subquery with select distinct. The logic you describe is more easily understood as a simple aggregation.
I'm not sure where dates comes from. It is not in your data model, but it is in your sample query.

How to select data from joined table as a table type?

I'd like to build de-normalised view that handles reference data in table type.
create table reftab (id number, name varchar2(40), details varchar2(1000));
/
create table basictab (id number, name varchar2(300), contract varchar2 (20));
/
create or replace type reftype is object (id number, name varchar2(40), details varchar2(1000));
/
create or replace type reftypetab as table of reftype;
/
insert into basictab values (1, 'aaa', 'c1');
insert into basictab values (2, 'aab', 'c1');
insert into basictab values (3, 'aaa', 'c2');
insert into basictab values (4, 'aaa', 'c3');
insert into reftab values (1, 'asd', 'aaa');
insert into reftab values (1, 'asg', 'ass');
insert into reftab values (1, 'ash', 'add');
insert into reftab values (1, 'asf', 'agg');
insert into reftab values (3, 'asd', 'aaa');
insert into reftab values (3, 'ad', 'aa');
insert into reftab values (4, 'asd', 'aaa');
insert into reftab values (4, 'as', 'a');
insert into values (4, 'ad', 'aa');
/
With such data I'd like to have view that contains 4 rows of basictab with additional column that is reftypetab and contains all ref data joined on id.
I know I can obtain it by:
CREATE OR REPLACE FUNCTION pipef (p_id IN NUMBER) RETURN reftypetab PIPELINED AS
BEGIN
FOR x IN (select * from reftab where id = p_id) LOOP
PIPE ROW(reftype(x.id, x.name, x.details));
END LOOP;
RETURN;
END;
/
SELECT id, pipef(id)
FROM reftab
group BY id;
/
but is there any better way without function to get the result?
Your current set-up gets:
SELECT id, pipef(id) as result
FROM reftab
group BY id;
ID RESULT(ID, NAME, DETAILS)
---------- ------------------------------------------------------------------------------------------------------------------------
1 REFTYPETAB(REFTYPE(1, 'asd', 'aaa'), REFTYPE(1, 'asg', 'ass'), REFTYPE(1, 'ash', 'add'), REFTYPE(1, 'asf', 'agg'))
4 REFTYPETAB(REFTYPE(4, 'asd', 'aaa'), REFTYPE(4, 'as', 'a'), REFTYPE(4, 'ad', 'aa'))
3 REFTYPETAB(REFTYPE(3, 'asd', 'aaa'), REFTYPE(3, 'ad', 'aa'))
You could use the collect() function to simplify that:
select id, cast(collect(reftype(id, name, details)) as reftypetab) as result
from reftab
group by id;
ID RESULT(ID, NAME, DETAILS)
---------- ------------------------------------------------------------------------------------------------------------------------
1 REFTYPETAB(REFTYPE(1, 'asd', 'aaa'), REFTYPE(1, 'asf', 'agg'), REFTYPE(1, 'ash', 'add'), REFTYPE(1, 'asg', 'ass'))
3 REFTYPETAB(REFTYPE(3, 'asd', 'aaa'), REFTYPE(3, 'ad', 'aa'))
4 REFTYPETAB(REFTYPE(4, 'asd', 'aaa'), REFTYPE(4, 'ad', 'aa'), REFTYPE(4, 'as', 'a'))
If you want information from basictab as well you can use a multiset operator:
select bt.id, bt.name,
cast(multiset(select reftype(rt.id, rt.name, rt.details)
from reftab rt where rt.id = bt.id) as reftypetab) as result
from basictab bt;
ID NAME RESULT(ID, NAME, DETAILS)
---------- ---------- ------------------------------------------------------------------------------------------------------------------------
1 aaa REFTYPETAB(REFTYPE(1, 'asd', 'aaa'), REFTYPE(1, 'asg', 'ass'), REFTYPE(1, 'ash', 'add'), REFTYPE(1, 'asf', 'agg'))
2 aab REFTYPETAB()
3 aaa REFTYPETAB(REFTYPE(3, 'asd', 'aaa'), REFTYPE(3, 'ad', 'aa'))
4 aaa REFTYPETAB(REFTYPE(4, 'asd', 'aaa'), REFTYPE(4, 'as', 'a'), REFTYPE(4, 'ad', 'aa'))
Further research gave me another way to do that:
SELECT id, CAST(COLLECT(reftype(r.id, r.name, r.details)) AS reftypetab) AS customer_ids
FROM reftab r group by id;
This looks much better but still I would ask if there are any opther ways to do that.
EDIT
Maybe that's not exactly what I was asking about but cursor expresion can give similar result.
SELECT id, cursor(select reftype(r.id, r.name, r.details) from reftab r where r.id = b.id) AS customer_ids
FROM basictab b;