Is there a way to get an employee's annual salary using their FTE in a SQL query?
This is the query to get the salary. How do I incorporate the FTE component?
SELECT papf.employee_number,papf.full_name,pj.NAME job,
pap.NAME as Designation ,pg.NAME as Grade , haou.NAME
ORGANIZATION,ppp.creation_date createDate,
ppp.PROPOSED_SALARY as salary
FROM per_all_people_f papf
,per_all_assignments_f paaf
,per_jobs pj
,per_grades pg
,hr_all_organization_units haou
,per_position_definitions ppd
,per_all_positions pap
,per_pay_proposals ppp
WHERE SYSDATE BETWEEN papf.effective_start_date AND papf.effective_end_date
AND papf.current_employee_flag = 'Y'
AND papf.employee_number IS NOT NULL
AND paaf.person_id = papf.person_id
AND SYSDATE BETWEEN paaf.effective_start_date AND paaf.effective_end_date
AND paaf.job_id = pj.job_id
AND paaf.organization_id = haou.organization_id
AND paaf.grade_id = pg.grade_id
AND paaf.position_id = pap.position_id
AND pap.position_definition_id = ppd.position_definition_id
AND ppp.pay_proposal_id in (SELECT MAX (pay_proposal_id)
FROM per_pay_proposals
WHERE assignment_id = paaf.assignment_id)
order by to_number(papf.employee_number)
I have found an excellent solution on here that will allow me to compare number working days between 2 dates excluding holidays. However what I cannot figure out is how to pass t1.ATTRIBUTE_DATE1 into the start_date and t1.CHECK_DATE into the end_date.
I have tried and put the With into the select it says too many arguments.
SELECT DISTINCT t1.invoice_date
, t1.creation_date
, t1.INVOICE_RECEIVED_DATE
, (t1.check_Date - t1.INVOICE_RECEIVED_DATE)
, ((t1.check_Date - t2.REPORT_SUBMIT_DATE)+3)
, ((t1.check_Date - t1.invoice_date)+3)
, t1.ATTRIBUTE_DATE1
, t1.invoice_num
, t1.payment_number
, t1.check_date
, t1.vendor_type_lookup_code
, t1.source
, t1.PAY_GROUP_LOOKUP_CODE
, t1.Batch_Name
, t1.Description
, t1.Vendor_Name
, t1.Amount_Paid
, t1.Invoice_ID
, t2.REPORT_SUBMIT_DATE
, t2.FINAL_APPROVAL_DATE
FROM ( SELECT DISTINCT APA.INVOICE_ID
, APA.INVOICE_DATE
, APA.CREATION_DATE
, APA.ATTRIBUTE_DATE1
, APA.INVOICE_NUM
, ACA.CHECK_NUMBER as PAYMENT_NUMBER
, ACA.CHECK_DATE
, APA.INVOICE_RECEIVED_DATE
, APA.CREATION_DATE
, SUP.VENDOR_TYPE_LOOKUP_CODE
, APA.SOURCE
, APA.PAY_GROUP_LOOKUP_CODE
, BAT.BATCH_NAME
, APA.DESCRIPTION
, APA.AMOUNT_PAID
, ACA.VENDOR_NAME
FROM AP_INVOICES_ALL APA
LEFT JOIN AP_INVOICE_LINES_ALL AIL
ON APA.INVOICE_ID= AIL.INVOICE_ID
LEFT JOIN AP_INVOICE_DISTRIBUTIONS_ALL AID
ON APA.INVOICE_ID = AID.INVOICE_ID AND AIL.LINE_NUMBER =
AID.INVOICE_LINE_NUMBER
JOIN AP_INVOICE_PAYMENTS_ALL AIP
ON APA.INVOICE_ID = AIP.INVOICE_ID
JOIN AP_CHECKS_ALL ACA
ON AIP.CHECK_ID = ACA.CHECK_ID
LEFT JOIN AP_BATCHES_ALL BAT
ON APA.BATCH_ID = BAT.BATCH_ID
LEFT JOIN POZ_SUPPLIERS_V SUP
ON APA.PARTY_ID = SUP.PARTY_ID
WHERE AID.LINE_TYPE_LOOKUP_CODE = 'ITEM'
AND APA.SOURCE NOT IN ('INVOICE GATEWAY' , 'B2B XML INVOICE')
AND ACA.STATUS_LOOKUP_CODE<> 'VOIDED'
AND APA.INVOICE_TYPE_LOOKUP_CODE NOT IN ('CREDIT' , 'PREPAYMENT')
AND ACA.CHECK_DATE BETWEEN :Start_Date AND :End_Date
AND BAT.BATCH_NAME IS NOT NULL) t1
LEFT JOIN (Select EXPENSE_REPORT_NUM
,REPORT_SUBMIT_DATE
,FINAL_APPROVAL_DATE
,EXPENSE_REPORT_TOTAL
FROM EXM_EXPENSE_REPORTS)t2
ON t1.INVOICE_NUM =t2.EXPENSE_REPORT_NUM
ORDER BY t1.CHECK_DATE ASC
With statment that I would like to use to give me days between t1.ATTRIBUTE_DATE1(can be blank) and t1.check_date
(WITH test_data AS
(
SELECT TO_DATE('01/01/2019', 'DD/MM/YYYY') AS start_date,-----t1.ATTRIBUTE_DATE1
TO_DATE('27/08/2019', 'DD/MM/YYYY') AS end_date------t1.check_date
FROM dual
),
all_dates AS
(
SELECT td.start_date, td.end_date, td.start_date + LEVEL-1 as week_day
FROM test_data td
CONNECT BY td.start_date + LEVEL-1 <= td.end_date)
SELECT TO_CHAR(week_day, 'MON'), COUNT(*)
FROM all_dates
WHERE to_char(week_day, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH') NOT IN
('SATURDAY','SUNDAY')
AND to_char(week_day, 'DD/MM/YYYY') NOT IN ( '01/01/2019', '25/12/2019',
'26/12/2019', '26/08/2019', '19/04/2019', '22/04/2019', '06/05/2019',
'27/05/2019')
GROUP BY TO_CHAR(week_day, 'MON')
)
Want to replace the the above with statement with this
(WITH test_data AS
(
SELECT TO_DATE(t1.ATTRIBUTE_DATE1, 'DD/MM/YYYY') AS start_date,
TO_DATE(t1.check_date, 'DD/MM/YYYY') AS end_date
FROM dual
),
all_dates AS
(
SELECT td.start_date, td.end_date, td.start_date + LEVEL-1 as week_day
FROM test_data td
CONNECT BY td.start_date + LEVEL-1 <= td.end_date)
SELECT TO_CHAR(week_day, 'MON'), COUNT(*)
FROM all_dates
WHERE to_char(week_day, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH') NOT IN ('SATURDAY','SUNDAY')
AND to_char(week_day, 'DD/MM/YYYY') NOT IN ( '01/01/2019', '25/12/2019', '26/12/2019', '26/08/2019', '19/04/2019', '22/04/2019', '06/05/2019', '27/05/2019')
GROUP BY TO_CHAR(week_day, 'MON')
)
I don't have a clue what your real issue is, but if you want to count working days between 2 dates you can use something like:
with test_data AS
(SELECT TO_DATE('01/01/2019', 'DD/MM/YYYY') AS start_date, -- t1.ATTRIBUTE_DATE1
TO_DATE('27/08/2019', 'DD/MM/YYYY') AS end_date -- t1.check_date
FROM dual
union all
SELECT TO_DATE('01/04/2019', 'DD/MM/YYYY') AS start_date, -- t1.ATTRIBUTE_DATE1
TO_DATE('10/08/2019', 'DD/MM/YYYY') AS end_date -- t1.check_date
FROM dual)
, dates as (
select trunc(sysdate,'YYYY') + level -1 bd from dual connect by level <= 250)
, evaluate_free as (
select bd
, case when to_char(bd, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH') IN ('SATURDAY','SUNDAY')
or to_char(bd, 'DD/MM/YYYY') IN ( '01/01/2019', '25/12/2019', '26/12/2019', '26/08/2019', '19/04/2019', '22/04/2019', '06/05/2019', '27/05/2019')
then 0 else 1 end free_work
from dates)
select start_date,end_date, sum(free_work) working_days
from evaluate_free, test_data
where bd between start_date and end_date
group by start_date,end_date
My query returns duplicate rows and I want to return only one row.
select papf.Full_Name,
papf.Employee_number,
papf.DatE_OF_BIRTH,
peef.last_update_date
/*,
petf1.ELEMENT_NAME as MedicalSchemeName*/
from per_all_people_f papf
,per_all_assignments_f paaf
,PAY_ELEMENT_ENTRIES_F peef
,pay_element_types_f petf
--,fnd_user fnu
where (papf.Employee_number) not in
(select
papf1.Employee_number
from per_all_people_f papfinner
,per_all_assignments_f paafinner
,PAY_ELEMENT_ENTRIES_F peefinner
,pay_element_types_f petfinner
where paafinner.person_id = papfinner.person_id
and peefinner.assignment_id = paafinner.assignment_id
and peefinner.element_type_id = petfinner.element_type_id
and upper(petf1.ELEMENT_NAME) like '%Condition%'
and SYSDATE BETWEEN papfinner.EFFECTIVE_START_DATE AND papfinner.EFFECTIVE_END_DATE
and SYSDATE BETWEEN paafinner.EFFECTIVE_START_DATE AND paafinner.EFFECTIVE_END_DATE
and SYSDATE BETWEEN peefinner.EFFECTIVE_START_DATE AND peefinner.EFFECTIVE_END_DATE
and SYSDATE BETWEEN petfinner.EFFECTIVE_START_DATE AND petfinner.EFFECTIVE_END_DATE
)
and SYSDATE BETWEEN papf.EFFECTIVE_START_DATE AND papf.EFFECTIVE_END_DATE
and SYSDATE BETWEEN paaf.EFFECTIVE_START_DATE AND paaf.EFFECTIVE_END_DATE
and SYSDATE BETWEEN peef.EFFECTIVE_START_DATE AND peef.EFFECTIVE_END_DATE
and SYSDATE BETWEEN petf.EFFECTIVE_START_DATE AND petf.EFFECTIVE_END_DATE
and upper(petf.ELEMENT_NAME) not like '%Condition%'
and rownum <= 10000
order by peef.last_update_date;
....
This query works properly and returns the correct results but the results are duplicated. I only need one unique row
One of the tables you are joining one is returning doubles or more. I bet it is "peef". Perhaps you can only show the MAX(last_update_date) and roll the rest up against that. So just GROUP BY.
select papf.Full_Name,
papf.Employee_number,
papf.DatE_OF_BIRTH,
last_update_date = MAX(peef.last_update_date)
...
GROUP BY
papf.Full_Name,
papf.Employee_number,
papf.DatE_OF_BIRTH
In my application each manager has a work pattern (for example Monday-Friday). But I also have a table "pattern_changes" where they can insert data if they cannot be present at work.
With the first query I can show who is available today, according to the pattern assigned to them:
SELECT distinct gu.first_name || ' ' || gu.last_name
FROM patterns pa JOIN fmanager_pattern fp
ON pa.id = fp.pattern_id
JOIN fmanagers fm
ON fm.id = fp.fmanager_id
JOIN gen_users gu
ON gu.user_id = fm.user_id
WHERE (TO_CHAR(pa.start_dt, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') LIKE TO_CHAR(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AND pa.start_dt < sysdate and pa.end_dt > sysdate)
OR (TO_CHAR(pa.end_dt, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') LIKE TO_CHAR(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AND pa.start_dt < sysdate and pa.end_dt > sysdate)
OR TO_CHAR(sysdate, 'D') BETWEEN TO_CHAR(pa.start_dt, 'D') AND TO_CHAR(pa.end_dt, 'D') AND pa.start_dt < sysdate and pa.end_dt > sysdate
OR TO_CHAR(sysdate, 'D')+7 BETWEEN TO_CHAR(pa.start_dt, 'D') AND TO_CHAR(pa.start_dt, 'D')+7 AND pa.start_dt < sysdate and pa.end_dt > sysdate
In the second query I can show who is not available today, according to the pattern_changes table.
SELECT fm.id, gu.first_name || ' ' || gu.last_name
FROM fmanagers fm JOIN pattern_changes pc
ON pc.fmanagers_id = fm.id
JOIN gen_users gu
ON gu.user_id = fm.user_id
WHERE pc.change_dt < sysdate and pc.end_dt > sysdate
OR pc.change_dt = to_char(sysdate)
OR pc.end_dt = to_char(sysdate))
For example, the first query returns: ADAM and EVA
The second query returns ADAM
So I just want to see EVA as a result.
I tried to do it with NOT IN or NOT EXISTS but neither of them work.
Can anybody help?
Thank you in advance
I am trying to add two tables and get the total days from two dates. But having the following simple issue: not a single-group group function.
This is what I've tried so far:
SELECT COUNT(status) AS "Present Days",
(SELECT TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY'))
FROM attendance m
INNER JOIN EMP_OFFICIAL k
ON k.EMPNO = m.EMPNO
WHERE m.empno='EMP00254'
AND m.status='P') AS "Total Days"
FROM attendance
WHERE empno = 'EMP00254'
AND status = 'P';
Can I get the days without using the DUAL?
First off, that subquery is most likely not scalar (it looks like you're assuming multiple rows can come from the attendance table) and second, it contains an unnecessary join..
What I would do instead is something like:
select count(*) as "Present Days",
to_date('01/10/2018', 'mm/dd/yyyy') - k.joining_date "Total Days"
from attendance a
inner join emp_official k on a.empno = k.empno
where a.empno = 'EMP00254'
and a.status = 'P'
group by to_date('01/10/2018', 'mm/dd/yyyy') - k.joining_date;
This does assume that the k.joining_date column is of DATE datatype and that 'k.empno' is a unique column.
If there is only one row in the EMP_OFFICIAL table for each employee then you could do:
SELECT COUNT(a.status) AS "Present Days",
TRUNC( SYSDATE ) - TRUNC( MIN( k.joining_date ) ) AS "Total Days"
FROM attendance a
RIGHT OUTER JOIN EMP_OFFICIAL k
ON ( k.EMPNO = a.EMPNO )
WHERE a.empno = 'EMP00254'
WHERE a.status = 'P';
or you could do the aggregation in a sub-query:
SELECT a."Present Days",
TRUNC( SYSDATE ) - TRUNC( k.joining_date ) AS "Total Days"
FROM (
SELECT EMPNO,
COUNT( status ) AS "Present Days"
FROM attendance
WHERE EMPNO = 'EMP00254'
AND status = 'P'
GROUP BY EMPNO
) a
RIGHT OUTER JOIN EMP_OFFICIAL k
ON ( k.EMPNO = a.EMPNO )
WHERE k.EMPNO = 'EMP00254';
Or you could use UNION ALL to query the two tables and have the result in two rows (rather than two columns):
SELECT 'Present Days' As type,
COUNT(status) AS Days
FROM attendance
WHERE empno = 'EMP00254'
WHERE status = 'P'
UNION ALL
SELECT 'Total Days',
TRUNC( SYSDATE ) - TRUNC( joining_date )
FROM EMP_OFFICIAL
WHERE empno = 'EMP00254';
Either remove COUNT(status) AS "Present Days" part and SELECT inside paranthesis :
SELECT (TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) "time difference" FROM attendance m
INNER JOIN EMP_OFFICIAL k ON k.EMPNO = m.EMPNO where m.empno='EMP00254' and m.status='P') AS "Total Days"
FROM attendance where empno = 'EMP00254' and status = 'P';
OR
use the following (add GROUP BY expression at the end of sql):
SELECT COUNT(status) AS "Present Days",
(TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) "time difference" FROM attendance m
INNER JOIN EMP_OFFICIAL k ON k.EMPNO = m.EMPNO where m.empno='EMP00254' and m.status='P') AS "Total Days"
FROM attendance where empno = 'EMP00254' and status = 'P'
GROUP BY (TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY'));
Since , groupped and non-groupped items can not be used together.
By the way, you don't need to use dual in your inline select statement like ( SELECT TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY') FROM DUAL ), just ( TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) is enough.