join three tables with count and sum in oracle - 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

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')

How to group and uniqe each row with ORACLE?

Anyone please help me, how to uniqe each row
SELECT T3.ID_JS,T5.DIVISI_AREA,T4.NAME_METHODE_REPAIR, T1.URUTAN AS SORT, TO_DATE(T1.TIME_FINISHED_WORK,'DD/MM/YYYY') AS DATE_FINISHED
FROM TB_WORK T1
JOIN TB_INSPECTION T2 ON T1.ID_INSPECTION=T2.ID_INSPECTION
JOIN TB_JOBSHEET T3 ON T2.ID_JS = T3.ID_JS
JOIN TB_METHODE_REPAIR T4 ON T1.ID_METHODE_REPAIR=T4.ID_METHODE_REPAIR
JOIN TB_DIVISI T5 ON T1.ID_DIVISI=T5.ID_DIVISI
where t3.id_js=142414
GROUP BY T3.ID_JS,T5.DIVISI_AREA,T4.NAME_METHODE_REPAIR, T1.URUTAN,TO_DATE(T1.TIME_FINISHED_WORK,'DD/MM/YYYY')
ORDER BY T3.ID_JS, TO_DATE(T1.TIME_FINISHED_WORK,'DD/MM/YYYY') desc
[Result] (http://prntscr.com/sfpuuq)
Those rows are unique, so I'll guess: there are two rows with sort = 3 and you'd want to have only one. If that's so, regarding the fact that date value is the only thing that makes difference, a simple way is to use aggregate function (such as min or max). I used max, but you can change it if you want:
SELECT t3.id_js,
t5.divisi_area,
t4.name_methode_repair,
t1.urutan AS sort,
MAX (TO_DATE (t1.time_finished_work, 'DD/MM/YYYY')) AS date_finished
FROM tb_work t1
JOIN tb_inspection t2 ON t1.id_inspection = t2.id_inspection
JOIN tb_jobsheet t3 ON t2.id_js = t3.id_js
JOIN tb_methode_repair t4
ON t1.id_methode_repair = t4.id_methode_repair
JOIN tb_divisi t5 ON t1.id_divisi = t5.id_divisi
WHERE t3.id_js = 142414
GROUP BY t3.id_js,
t5.divisi_area,
t4.name_methode_repair,
t1.urutan
ORDER BY t3.id_js, date_finished DESC
You'd remove date column from GROUP BY; besides, if you wanted to select distinct rows, why didn't you apply select distinct instead of using group by? Result is the same, but - group by is generally used with aggregates, not to return distinct result.

speed up a query with multiple inner joins in ms access

as tittle says i need to improve this query that i have made in ms access, the tables are from a linked DB. i can't index them. i need help to understand where it is taking so long... is there any function like
EXPLAIN to access? do i need to put more columns in some sort of group by? what i need to do to improve the speed of this (the group by of first select has 4M rows but after grouped only has 321k and it takes 20min to run when laptop doesn't crashes)
SELECT a.SEQ_NO,
b.SKU,
b.maxdate,
(a.BASE_COST/a.EXCHANGE) AS BASE_COST,
(a.NET_COST/a.EXCHANGE) AS NET_COST,
(a.NET_NET_COST/a.EXCHANGE) AS EXCHAGED_NET_NET_COST,
a.NET_NET_COST,
(a.DEAD_NET_NET_COST/a.EXCHANGE) AS DEAD_NET_NET_COST,
(a.LANDED_COST/a.EXCHANGE) AS LANDED_COST,
(a.POSEIMA/a.EXCHANGE) AS POSEIMA,
(a.TOTAL_BONUS/a.EXCHANGE) AS TOTAL_BONUS,
(a.IEC/a.EXCHANGE) AS IEC,
(a.IEC_BONUS/a.EXCHANGE) AS IEC_BONUS,
(a.ECO_INVOICE_FORN/a.EXCHANGE) AS ECO_INVOICE_FORN_SYSTEM,
(a.ECO_INVOICE/a.EXCHANGE) AS ECO_INVOICE_SYSTEM,
(a.ECO_MERCHANDISE/a.EXCHANGE) AS ECO_MERCHANDISE_SYSTEM,
c.SUPPLIER,
c.SUP_NAME,
d.UPC,
d.PRIMARY_UPC_IND,
f.BRAND,
g.DEPT,
g.DESC_UP,
g.CLASS,
g.SUBCLASS,
h.AV_COST,
h.UNIT_RETAIL AS Last_of_unit_retail,
h.STATUS, i.[UNIT VALUE],
i.[INITIAL DATE],
i.[END DATE] INTO PRICELIST
FROM (((((((RMS_MC_NB_PRICELIST_COST AS a INNER JOIN (SELECT MAX(SEQ_NO) AS
ID, SKU, MAX(ACTIVE_DATE) AS maxdate FROM RMS_MC_NB_PRICELIST_COST GROUP BY
SKU) AS b ON a.SEQ_NO = b.ID)
INNER JOIN RMS_MC_SUPS AS c ON a.SUPPLIER = c.SUPPLIER)
INNER JOIN RMS_MC_UPC_EAN AS d ON b.SKU = d.SKU)
INNER JOIN RMS_MC_WIN_ATTRIBUTES AS e ON b.SKU = e.SKU)
INNER JOIN RMS_MC_NB_BRAND AS f ON e.NB_BRAND_NO = f.BRAND_NO)
INNER JOIN RMS_MC_DESC_LOOK AS g ON b.SKU = g.SKU)
INNER JOIN RMS_MC_WIN_STORE AS h ON b.SKU = h.SKU)
LEFT JOIN MAPA_APOIOS_SISO AS i ON b.SKU = i.[# ARTICLE];

Oracle 11g - Selecting multiple records from a table column

I was just wondering how you select multiple records from a table column. Please see below the query.
SELECT DISTINCT DEPARTMENT_NAME, CITY, COUNTRY_NAME
FROM OEHR_DEPARTMENTS
NATURAL JOIN OEHR_EMPLOYEES
NATURAL JOIN OEHR_LOCATIONS
NATURAL JOIN OEHR_COUNTRIES
WHERE JOB_ID = 'SA_MAN' AND JOB_ID = 'SA_REP'
;
Basically, I want to be able to select records from the table column I have, however when you use AND it only displays SA_MAN and not SA_REP. I have also tried to use OR and it displays no rows selected. How would I actually be able to select both Job ID's without it just displaying one or the other.
Sorry this may sound like a stupid question (and probably not worded right), but I am pretty new to Oracle 11g SQL.
For your own comfort while debugging, I suggest you to use inner joins instead of natual joins.
That where clause is confusing, if not utterly wrong, because you don't make clear which tables' JOB_ID should be filtered. Use inner joins, give aliases to tables, and refer to those aliases in the where clause.
select distinct DEPARTMENT_NAME, CITY, COUNTRY_NAME
from OEHR_DEPARTMENTS t1
join OEHR_EMPLOYEES t2
on ...
join OEHR_LOCATIONS t3
on ...
join OEHR_COUNTRIES t4
on ...
where tn.JOB_ID = 'SA_MAN' AND tm.JOB_ID = 'SA_REP'
After rephrasing your query somehow like this, you'll have a clearer view on the logical operator you'll have to use in the where clause, which I bet will be an OR.
EDIT (after more details were given)
To list the departments that employ staff with both 'SA_MAN' and 'SA_REP' job_id, you have to join the departments table with the employees twice, once with the filter job_id='SA_MAN' and once with job_id='SA_REP'
select distinct DEPARTMENT_NAME, CITY, COUNTRY_NAME
from OEHR_DEPARTMENTS t1
join OEHR_EMPLOYEES t2
on t1.department_id = t2.department_id --guessing column names
join OEHR_EMPLOYEES t3
on t1.department_id = t3.department_id --guessing column names
join OEHR_LOCATIONS t4
on t1.location_id = t4.location_id --guessing column names
join OEHR_COUNTRIES t5
on t4.country_id = t5.country_id --guessing column names
where t2.job_id = 'SA_MAN' and t3.job_id = 'SA_REP'
order by 1, 2, 3

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