Select a field from a table for two different values from two different tables - oracle

I have four tables as shown below.HL_STUDENT,HL_SEM1_CRS and HL_SEM2_CRS tables that has STUDENT as the primary key where as HL_TITLE doesn't have a STUDENT field and has the course number (CRS_NBR) as the key.
HL_STUDENT A
HL_SEM1_CRS B
HL_SEM2_CRS C
HL_CRS_TITLE D
I need to get the STUDENT,CRS-1,CRS1-TITLE-DESC,CRS-2,CRS2-TITLE-DESC as shown below.I need course descripion for both Course 1 and Course 2.
STUDENT CRS-1 CRS1-TITLE-DESC CRS-2 CRS2-TITLE-DESC
1 25 MATH 35 HISTORY
2 35 HISTORY 25 MATH
I was thinking of getting the solution by joining the HL_CRS_TITLE Table twice with different ALIAS as shown below.
SELECT DISTINCT A.STUDENT
,B.CRS_1
,D.CRS_TITLE_DESC
,C.CRS_2
,E.CRS_TITLE_DESC
FROM HL_STUDENT A
LEFT JOIN HL_SEM1_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS_1
LEFT JOIN HL_SEM2_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE E ON E.CRS_NBR = B.CRS_2
Can you please suggest a better way to get the solution?
I'm querying against ORACLE DB.
Thanks for your help.

I think you are looking for a way to get course title for the records of both the semesters without the need of joining HL_CRS_TITLE two times.
I ran into a similar situation once and created a function to serve the purpose.
--Function DDL
CREATE OR REPLACE FUNCTION F_GET_CRS_TITLE (IN_CRS_NBR IN NUMBER)
RETURN VARCHAR2
RESULT_CACHE
AS
LV_CRS_TITLE_DESC VARCHAR2(100);
BEGIN
SELECT CRS_TITLE_DESC
INTO LV_CRS_TITLE_DESC
FROM HL_CRS_TITLE
WHERE CRS_NBR = IN_CRS_NBR;
RETURN LV_CRS_TITLE_DESC;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'NO_COURSE_EXISTS';
END;
/
You can re-write your query like below:
SELECT DISTINCT A.STUDENT
,B.CRS_1
,F_GET_CRS_TITLE(B.CRS_1)
,C.CRS_2
,F_GET_CRS_TITLE(C.CRS_2)
FROM HL_STUDENT A
LEFT JOIN HL_SEM1_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_SEM2_CRS C ON A.STUDENT = C.STUDENT;

As I understand the problem is in duplicates if you join students and courses in first semester and join it in second semester you see cross joined courses?
If its true you may use FULL JOIN between courses and join it with students and titles
SELECT DISTINCT A.STUDENT
,B.CRS_1
,D.CRS_TITLE_DESC
,B.CRS_2
,E.CRS_TITLE_DESC
FROM HL_STUDENT A
JOIN (SELECT NVL(B1.STUDENT, B2.STUDENT) as STUDENT, B1.CRS_1, B2.CRS_2
FROM HL_SEM1_CRS B1
FULL JOIN HL_SEM2_CRS B2 ON B1.STUDENT = B2.STUDENT AND B1.CRS_1 = B2.CRS_2) B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS_1
LEFT JOIN HL_CRS_TITLE E ON E.CRS_NBR = B.CRS_2
example without double join to HL_CRS_TITLE.
SELECT DISTINCT A.STUDENT
,B.CRS_1
,nvl2(B.CRS_1, D.CRS_TITLE_DESC, null) as CRS_TITLE_DESC_1
,B.CRS_2
,nvl2(B.CRS_2, D.CRS_TITLE_DESC, null) as CRS_TITLE_DESC_2
FROM HL_STUDENT A
JOIN (SELECT NVL(B1.STUDENT, B2.STUDENT) as STUDENT,nvl(B1.CRS_1, B2.CRS_2) as CRS,B1.CRS_1, B2.CRS_2
FROM HL_SEM1_CRS B1
FULL JOIN HL_SEM2_CRS B2 ON B1.STUDENT = B2.STUDENT AND B1.CRS_1 = B2.CRS_2) B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS

Related

Error when running a sub query in Oracle SQL

I am trying to join three tables using a sub query.
The result of the first left outer join is to be used with another table to get a composite view with all attributes.
I am getting an error where the compile says, Unknown Command for the table in the second join clause.
When I create two independent views and then join then it works fine.
(select
l.ENROLLED_CONTENT,
l.LEARNING_ENROLLMENT_LEARNER,
l.EMPLOYEE_ID,
l.JOB_FAMILY_GROUP,
l.EMPLOYEE_TYPE,
l.JOB_FAMILY,
l.LEARNING_ENROLLMENT,
l.COMPLETION_STATUS,
l.COMPLETION_DATE,
l.EXPIRATION_DATE,
l.CF_LRV_LEARNING_CONTENT_NUMBER,
l.LEARNING_CONTENT_DETAIL,
l.LEARNING_CONTENT_TYPE,
l.LESSON_TYPE,
e.id# "WK_WORKER_ID"
from tgt_workday.learning l
left outer join ods_hrmaster.employee e
on l.EMPLOYEE_ID = e.employee#) t1
left outer join ( select
per_ids_id,
per_id,
id_pureid from
ods_pure.person_ids
) t2 on t1.wk_worker_id = t2.value where t2.type = 'Employee ID';
You can write it in a simple way. There is no need to make sub-queries as:
SELECT L.ENROLLED_CONTENT,
L.LEARNING_ENROLLMENT_LEARNER,
L.EMPLOYEE_ID,
L.JOB_FAMILY_GROUP,
L.EMPLOYEE_TYPE,
L.JOB_FAMILY,
L.LEARNING_ENROLLMENT,
L.COMPLETION_STATUS,
L.COMPLETION_DATE,
L.EXPIRATION_DATE,
L.CF_LRV_LEARNING_CONTENT_NUMBER,
L.LEARNING_CONTENT_DETAIL,
L.LEARNING_CONTENT_TYPE,
L.LESSON_TYPE,
E.ID# "WK_WORKER_ID"
FROM TGT_WORKDAY.LEARNING L
LEFT OUTER JOIN ODS_HRMASTER.EMPLOYEE E
ON L.EMPLOYEE_ID = E.EMPLOYEE#
LEFT OUTER JOIN ODS_PURE.PERSON_IDS T2
ON E.ID# = T2.VALUE
AND T2.TYPE = 'Employee ID';
Once you use the outer joined table's column in WHERE clause, It will result in the same result as inner join(there is another ways to use it in WHERE clause though). So it is better to avoid using outer joined table's column in the WHERE clause.
Try as
SELECT *
FROM ( (SELECT l.ENROLLED_CONTENT,
l.LEARNING_ENROLLMENT_LEARNER,
l.EMPLOYEE_ID,
l.JOB_FAMILY_GROUP,
l.EMPLOYEE_TYPE,
l.JOB_FAMILY,
l.LEARNING_ENROLLMENT,
l.COMPLETION_STATUS,
l.COMPLETION_DATE,
l.EXPIRATION_DATE,
l.CF_LRV_LEARNING_CONTENT_NUMBER,
l.LEARNING_CONTENT_DETAIL,
l.LEARNING_CONTENT_TYPE,
l.LESSON_TYPE,
e.id# "WK_WORKER_ID"
FROM tgt_workday.learning l
LEFT OUTER JOIN ods_hrmaster.employee e
ON l.EMPLOYEE_ID = e.employee) t1
LEFT OUTER JOIN
(SELECT per_ids_id, per_id, id_pureid FROM ods_pure.person_ids) t2
ON t1.wk_worker_id = t2.VAL AND t2.TYPE = 'Employee ID')

join three tables with count and sum in oracle

I have three tables and trying to join these tables with count(working_days) and sum(Overtime) functions but overtime is not showing correct i am trying the query is.
SELECT E.EMP_CODE,E.EMP_NAME,
COALESCE(SUM(O.OVERTIME),0) AS OVERTIME,COALESCE(COUNT(C.EMP_ATT),0) WORKED_DAYS
FROM EMP E
LEFT JOIN OVERTIME O
ON E.EMP_CODE = O.EMP_CODE
LEFT JOIN ATT_REG C
ON E.EMP_CODE=C.EMP_CODE
GROUP BY E.EMP_CODE,E.EMP_NAME
ORDER BY EMP_CODE
Yes, You will get multiple records of the overtime for employees as shift date (or similar in your table) is missing in the join.
SELECT E.EMP_CODE,E.EMP_NAME,
COALESCE(SUM(O.OVERTIME),0) AS OVERTIME,
COALESCE(COUNT(C.EMP_ATT),0) WORKED_DAYS
FROM EMP E
LEFT JOIN ATT_REG C
ON E.EMP_CODE=C.EMP_CODE
LEFT JOIN OVERTIME O
ON E.EMP_CODE = O.EMP_CODE
AND C.SHIFTDATE = O.SHIFDATE -- YOU NEED SOMETHING LIKE THIS
GROUP BY E.EMP_CODE,E.EMP_NAME
ORDER BY EMP_CODE

How to create an Oracle One-to-Many Statistics View?

I have three tables need to join statistics.The A table corresponds to multiple rows in the B table, and B has a state. I need to count the number of scrapped statuses in B and some attributes of the rows in non-rejected state, and finally grouped by A's barcode, but I don't know how to query B in different states in a query and count them in an A. I tried following codes, but nothing queried.
select
a.barcode barcode
, count(b.id) effectiveNum
, count(b2.id) scraps
, sum(b.x * c.y)
from A a
, B b
, B b2
, C c
where a.id = b.Aid
and a.id = b2.Aid
and b2.state = -1000
and b.id = c.Bid
group by a.barcode
Who can help me please?
I think you need to LEFT-JOIN in order to accept empty Lists in B. But as APC said, some example-data would be great.
SELECT a.barcode barcode,
COUNT (b.id) effectiveNum,
COUNT (b2.id) scraps,
SUM (b.x * c.y)
FROM A a
LEFT JOIN B b ON a.id = b.Ai
LEFT JOIN B b2 ON a.id = b2.Aid AND b2.state = -1000
LEFT JOIN C c ON b.id = c.Bid
WHERE 1 = 1 -- Filter A here if needed
GROUP BY a.barcode

Left outer join is null- additional conditions

I'm trying to find all entries in table a, where there is no matching entry in table b for one specific column (order). I'm using the following:
SELECT *
FROM a
LEFT OUTER JOIN b
ON a.id = b.id
WHERE b.order IS NULL
AND a.result>10
However, the last condition for result doesn't seems to work. It simply lists all the entries from table a, regardless whether result is more than 10 or not.
Any way around this?
Shouldn't your query be as below?
SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.id WHERE b.id IS NULL AND a.result>10

Linq query only returning 1 row

Dim ds = From a In db.Model
Join b In db.1 On a.id Equals b.ID
Join c In db.2 On a.id Equals c.ID
Join d In db.3 On a.id Equals d.ID
Join f In db.4 On a.id Equals f.ID
Select a.id, a.Ref, a.Type, a.etc
Above is my linq query. At the moment I am only getting the first row from the db returned when there are currently 60 rows. Please can you tell me where I am going wrong and how to select all records.
Thanks in advance!
UPDATE:
When I take out all the joins like so:
Dim ds = From a In db.1, b In db.2, c In db.3, d In db.4, f In db.5
Select a.id, a.Ref, a.type, b.etc, c.etc, d.etc
I get a system.outofmemory exception!
You're only going to get a row produced when all of the joins match - in other words, when there's a row from Model with an AP, an Option, a Talk and an Invoice. My guess is that there's only one of those.
LINQ does an inner join by default. If you're looking for a left outer join (i.e. where a particular row may not have an Invoice, or a Talk etc) then you need to use a group join, usually in conjunction with DefaultIfEmpty.
I'm not particularly hot on VB syntax, but this article looks like it's what you're after.

Resources