Order by sequence number in case - possibility - sql

I got a little bit complicated report in sql for my HR dep. and one of fields is that if someone got social insurance.
a must have case for it ( if some assumptions are met then view Yes otherwise No ) the problem is that people are employyed more then one time and not always want to have social insurance.
the data looks like:
https://fojlww.am.files.1drv.com/y4mawp7Xs7HahMkb_h_bP7xuD_UIHAfDF3dvZ1iPLD5kGMFjHpcJpEDUD3g8TyNmT5mxgZbU6LLJPhWGivDtZEy8i4e3lz32jMBIB7yw5MzRO4U5PiGdoWtbIT02Qdk-9_eGfxTUgkGcE-g4JNQ80C6TK2PSUmlIzBlTmo99knOJotmSnLbqJevrF5CB3jmdKtLVGEfdDY4dLHoCcnWWZV10Q?width=1306&height=320&cropmode=none
(CASE WHEN (select s.emp_no from SSI_DATA s where
s.C_NO_CONTRIBUTIONS = 'FALSE' and OBLIG_PENSION_INSUR = 'TRUE' and s.emp_no = cp.emp_no and s.company_id = cp.company_id and
(s.C_NO_CONTRIB_SINCE <= '2019-10-10' or s.C_NO_CONTRIB_SINCE is null or s.C_NO_CONTRIB_SINCE = 'FALSE' ) and rownum = 1
<p>order by s.seq desc</p>
--and s.seq = ( select max(seq) from SSI_DATA where emp_no = cp.emp_no and company_id = cp.company_id)
) = cp.emp_no
THEN 'Y'
ELSE 'N' END)

Related

Oracle SQL grand query does not recognize column selected in with clause

I have sub query as table using with clause, the weird thing is that if I remove condition person_type.person.id = A.person_id it works fine, so it will recognize person_type.effective_start_date and person_type.effective_end_date from person_type with clause, but not person_id as it says person_type.person_id invalid identifier, what's the issue here?
with person_type as (
SELECT pptt.user_person_type, paam.person_id, paam.effective_start_date,paam.effective_end_date
FROM fusion.PER_PERSON_TYPES ppt,
fusion.PER_PERSON_TYPES_TL pptt,
fusion.per_all_assignments_m paam
WHERE 1 = 1
AND ppt.person_type_id = pptt.person_type_id
AND pptt.language = USERENV('LANG')
AND ppt.person_type_id = paam.person_type_id
AND paam.assignment_type = 'E'
AND PAAM.EFFECTIVE_LATEST_CHANGE = 'Y'
AND PAAM.Assignment_Status_Type = 'ACTIVE'
AND paam.primary_assignment_flag = 'Y'
)
SELECT ....
FROM (SELECT ... FROM ... WHERE ...) A,
person_type
WHERE person_type.person.id = A.person_id
AND TRUNC(A.date_earned) BETWEEN person_type.effective_start_date AND person_type.effective_end_date
AND ...
Oracle is right, you've made a mistake.
with person_type as
(
SELECT pptt.user_person_type, paam.person_id, ...
) ^
|
WHERE person_type.person.id = A.person_id
^
|
see anything strange here?

Finding Conversion Rate

I have two column tables with subscription result for each project. I need to know the conversion rate for each experiment.
My tables are:
And my desired result is
conversion is any user for whom there is a subscription start event in addition to the trial start event (all users have a trial start event). If a user is in multiple experiments at the same time, it’s ok to count them towards the conversion rate of each experiment, also want to only return one row per experiment.
I have done a inner join to get subscription event and experiment id together but able to process further. Any help is appreciated/
My inner join table looks like
I think this is a left join with some filtering and aggregation:
select e.experiment_id,
(count(case when experiment_assignment = 'test' then s.user_id end) * 1.0 /
sum(case when experiment_assignment = 'test' then 1 else 0 end)
) as test_conversion_rate,
(count(case when experiment_assignment = 'control' then s.user_id end) * 1.0 /
sum(case when experiment_assignment = 'control' then 1 else 0 end)
) as control_conversion_rate
from experiment e left join
subscription s
on s.user_id = e.user_id and
s.subscription_event = 'subscription_start'
group by e.experiment_id;
select experiment_id,
(count(case when experiment_assignment = 'test' and subscription_event = “subscriptipon_start” then user_id end)*100 /
count(case when experiment_assignment = 'test' and subscription_event = “trial_start” then user_id )
) as test_conversion_rate,
(count(case when experiment_assignment = 'control' and subscription_event = “subscriptipon_start” then user_id end) * 100 /
count(case when experiment_assignment = 'control' and subscription_event = “trial_start” then user_id end)
) as control_conversion_rate
from experiment inner join subscription
on user_id
group by experiment_id;

How to tune this query in Oracle 11g

I have been asked to tune the below query and would like to know if there is any better way to tune it?
SELECT req_dtl.lab_ord_occ_test_id ,
req_dtl.order_ref_no ,
req_dtl.accession_no ,
req_dtl.test_code ,
req_dtl.test_name ,
req_dtl.test_id ,
req_dtl.schedule_id ,
req_dtl.lab_ord_occ_id ,
req_dtl.order_type ,
lab_occ.facility_id ,
lab_occ.patient_id ,
lab_occ.order_draw_dt ,
hdr.source_system ,
(SELECT CORPORATION_ACRONYM
FROM corporation c,
facility f
WHERE c.corporation_id = f.corporation_id
AND f.facility_id = lab_occ.facility_id) AS corporation_acronym,
tst.container ,
lab_occ.order_duration_type ,
occ_test.mnc_yn
FROM ORDER_REQUISITION_HEADER hdr ,
ORDER_REQUISITION_DETAIL req_dtl ,
LAB_ORDER_OCC_TEST occ_test ,
LAB_ORDER_OCC lab_occ ,
TEST tst
WHERE hdr.requisition_hdr_id = in_requisition_hdr_id
AND hdr.msg_sent_to_lab_yn = 'Y'
AND req_dtl.requisition_hdr_id = hdr.requisition_hdr_id
AND occ_test.lab_order_occ_test_id = req_dtl.lab_ord_occ_test_id
AND req_dtl.test_id = tst.test_id
AND tst.accession_type NOT LIKE 'CMP%'
AND occ_test.status != 'R'
AND occ_test.lab_order_occ_id = lab_occ.lab_order_occ_id
AND lab_occ.status = 'A'
AND occ_test.created_dt >= hdr.msg_sent_to_lab_dt
AND NVL(occ_test.test_sent_to_lab_yn,'N') = 'N'
AND NOT EXISTS
(SELECT orddata.*
FROM MISSING_ORDER_DATA orddata,
TEST_CONFIG_HOLD_AOE tcha
WHERE orddata.test_id = tcha.test_id
AND tcha.active_yn = 'Y'
AND orddata.status_flag = 'A'
AND orddata.answer IS NULL
AND orddata.msg_sent_to_lab_yn = 'N'
AND orddata.lab_order_occ_test_id=occ_test.lab_order_occ_test_id
)
ORDER BY req_dtl.accession_no;
In the execution plan no tables are going for full table scan.Only nested loops are more.
*Suggest better way to tune this query *
AND NOT EXISTS
(SELECT orddata.*
FROM MISSING_ORDER_DATA orddata,
TEST_CONFIG_HOLD_AOE tcha
WHERE orddata.test_id = tcha.test_id
AND tcha.active_yn = 'Y'
AND orddata.status_flag = 'A'
AND orddata.answer IS NULL
AND orddata.msg_sent_to_lab_yn = 'N'
AND orddata.lab_order_occ_test_id=occ_test.lab_order_occ_test_id
)
could be moved to FROM
FROM
...
LEFT JOIN (SELECT DISTINCT orddata.lab_order_occ_test_id
FROM MISSING_ORDER_DATA orddata,
TEST_CONFIG_HOLD_AOE tcha
WHERE orddata.test_id = tcha.test_id
AND tcha.active_yn = 'Y'
AND orddata.status_flag = 'A'
AND orddata.answer IS NULL
AND orddata.msg_sent_to_lab_yn = 'N'
) missing ON missing.lab_order_occ_test_id = occ_test.lab_order_occ_test_id
WHERE missing.lab_order_occ_test_id IS NULL
Also you should move the acronym
FROM
...
INNER JOIN (SELECT CORPORATION_ACRONYM, f.facility_id
FROM corporation c,
facility f
WHERE c.corporation_id = f.corporation_id) acr ON
acr.facility_id = lab_occ.facility_id)
...Additionally, the TEST object must have an index on accession_type otherwise the tst.accession_type not like 'CMP%' clause will be slower than necessary.
Also, the clause: NVL(occ_test.test_sent_to_lab_yn,'N') = 'N' is essentially an outer join on partially-validated data. Does the test_sent_to_lab_yn column in occ_test contain nulls? If not, consider using an IN clause along with a valid list. [it looks like a yes/no column, maybe this should be equality on 'Y' and get someone to clean up the nulls?]
Please post the explain plan so we can suggest a re-ordering of the predicates in order to minimize the row-returns in first clause....and make HINT suggestions.

TSQL - Multiple Values in INSERT (because of joins)

Im trying to insert a data from one database to another. This is what i have so far, on the select side:
USE [db2]
SELECT
sP.pers_FirstName
,sp.pers_LastName
,sPH.Phon_Number
,CASE WHEN LEFT(sPH.Phon_Number, 2) = '04' THEN sPH.Phon_number ELSE NULL END
,CASE WHEN sp.pers_gender = 1 THEN 'M' WHEN sp.pers_gender = 2 THEN 'F' ELSE 'U' END
,CASE
WHEN sP.pers_salutation = '10' THEN 8
WHEN sp.pers_salutation = '6' THEN 2
WHEN sp.pers_salutation = '7' THEN 1
WHEN sp.pers_salutation = '8' THEN 4
WHEN sp.pers_salutation = '9' THEN 5
WHEN sp.pers_salutation = 'APROF' THEN 6
WHEN sp.pers_salutation = 'Ms.' THEN 4
WHEN sp.pers_salutation = 'PROF' THEN 6
END
,sp.pers_dob
,sp.pers_CreatedDate
,sp.pers_UpdatedDate
,'Candidate'
,1
,e.Emai_EmailAddress
,sP.pers_personID
FROM [db1].dbo.person sP
LEFT JOIN [db1].dbo.PhoneLink sPL ON sp.pers_personID = sPL.PLink_recordID
LEFT JOIN [db1].dbo.Phone sPH ON sPL.PLink_PhoneId = sPH.Phon_PhoneID
LEFT JOIN [db1].dbo.EmailLink eL ON sP.pers_personID = eL.ELink_RecordID
LEFT JOIN [db1].dbo.Email e ON eL.Elink_EmailID = e.Emai_EmailID
WHERE
(
sP.pers_employedby NOT IN (
'Aspen'
,'ACH'
)
)
OR
(
sP.pers_employedby IN (
'Aspen'
,'ACH'
)
AND sP.pers_personID NOT IN (
SELECT c.oppo_PrimaryPersonID FROM [SageCRM].dbo.Opportunity c
WHERE (c.oppo_contractcompleted <= '2016-01-01' OR c.oppo_contractterminated <= '2016-01-01') and c.Oppo_Deleted is null)
AND
sp.pers_isanemployee != 'ECHO'
AND sP.pers_personID IN (
SELECT c.oppo_PrimaryPersonID FROM [SageCRM].dbo.Opportunity c
WHERE c.oppo_Status != 'In Progress' OR c.oppo_Status = 'Completed')
AND sP.pers_dod IS NULL
AND sP.pers_FirstName NOT LIKE '%test%'
AND sP.pers_LastName NOT LIKE '%test%'
AND sp.pers_isanemployee != 'SalesContact'
)
Due to the fact that each person record can have multiple phone numbers linked to them, i end up with multiple records for each person, which obviously wont work as i will end up with duplicates when i actually insert the data.
The problem is, that i need to have all of the phone numbers for each record, just displayed in a different field (home phone, work phone, mobile phone).
Any Ideas, other than doing this in a separate insert statement for each phone / email link?
-------- EDIT: -----------------------------------------------------------------
Ok so, my bad for not giving you enough information. Both of your answers were good answers so thanks for that (#Horaciux, #John Wu).
However, there is no phoneType column, just a phone number. That being said, since every mobile starts with 04 and every home phone with anything else, i can pretty easily distinguish between the two phone types.
There are duplicates in the phone table though, so i will have to delete these, most likely via CTE, shouldn't be too hard.
So, i will end up with something like this for the two phone numbers:
SELECT (phon_number FROM phone p INNER JOIN PhoneLink p1 on p1.PhoneLinkID = p.PhoneLink WHERE LEFT(p.Phon_Number, 2) = '04')
SELECT (phon_number FROM phone p INNER JOIN PhoneLink p1 on p1.PhoneLinkID = p.PhoneLink WHERE LEFT(p.Phon_Number, 2) != '04')
My duplicate removal will be something like this:
WITH CTE AS
(
SELECT phon_linkID, phon_phonNumber, ROW_NUMBER() OVER (PARTITION BY phon_phonNumber ORDER BY phon_linkID) AS RN
FROM phone
)
DELETE FROM CTE WHERE RN<>1
Two easy steps.
Get rid of the joins to the phone number table.
Lookup the phone numbers per record by using a subquery in the select clause, one for each type of phone. Example
SELECT sP.pers_FirstName,
sP.pers_LastName,
(SELECT Phon_Number FROM Phone p JOIN PhoneLink pl ON pl.PhoneLinkID = p.PhoneLinkID WHERE pl.Person_ID = sP.pers_personID AND pl.Type = 'WORK') WorkPhone,
(SELECT Phon_Number FROM Phone p JOIN PhoneLink pl ON pl.PhoneLinkID = p.PhoneLinkID WHERE pl.Person_ID = sP.pers_personID AND pl.Type = 'HOME') HomePhone
FROM person
Without knowing your table's structure, I'll do some example.
select person.id,
max(case when phone.type='home' then phone.vlaue else 0 end) 'home',
max(case when phone.type='work' then phone.vlaue else 0 end) 'work'
from person,phone where...
group by person.id
Then use this query to join all other tables needed

SQL SP runs Slow

Hi
I am using an SP which takes 7 minutes in a server which has 7336 recrds
and 6seconds in another server which has 3500 records.
Can anybody help me to know why is it happening?
Thanks,
-Divya
THE SP:
SELECT WORKSHEET_ID
FROM PERSON PER
INNER JOIN PERSON EMPLEE
ON EMPLEE.PERSON_ID = PER.PERSON_ID
AND
dbo.FN_CHECKRPTSECURITY(EMPLEE.PERSON_ID, #p_SEC_ACCOUNT_ID) > 0
LEFT JOIN SEARCH_ASSIGNMENT_VW PERSON_ASGN
ON PERSON_ASGN.ASSIGNMENT_ID =
dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
LEFT JOIN LOOKUP EMPLEE_ASGN_STAT
ON EMPLEE_ASGN_STAT.TYPE_ = 'ASSIGNMMENT_STATUS_CODE'
AND EMPLEE_ASGN_STAT.CODE = PERSON_ASGN.ASGN_STAT_CODE
INNER JOIN
(SELECT w1.ASSIGNMENT_ID, w1.WORKSHEET_ID, w1.EFFECTIVE_DATE, w1.APPROVED_BY, w3.CREATED_BY
FROM WORKSHEET_PAYROLL_VW w1
INNER JOIN WORKSHEET w3
ON w3.WORKSHEET_ID = w1.WORKSHEET_ID
WHERE w1.EFFECTIVE_DATE = CASE
WHEN #p_MOST_RECENT_ONLY = 'Y'
THEN (SELECT MAX(w2.EFFECTIVE_DATE)
FROM WORKSHEET_PAYROLL_VW w2
WHERE w1.ASSIGNMENT_ID = w2.ASSIGNMENT_ID
AND (ISNULL(#p_WKS_EFFECTIVE_DATE,w2.EFFECTIVE_DATE) =w2.EFFECTIVE_DATE))
ELSE ISNULL(#p_WKS_EFFECTIVE_DATE,w1.EFFECTIVE_DATE)
END
)
PERSON_WKS
ON PERSON_WKS.ASSIGNMENT_ID = dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
INNER JOIN
(SELECT ASSIGNMENT_ID, VALUE
FROM ASSIGNMENT_HISTORY AH
WHERE FIELD_NAME ='HOME PAYROLL GROUP'
AND EFFECTIVE_DATE = (SELECT MAX(EFFECTIVE_DATE)
FROM ASSIGNMENT_HISTORY
WHERE ASSIGNMENT_ID = AH.ASSIGNMENT_ID
AND EFFECTIVE_DATE <=getDate()
AND FIELD_NAME = 'HOME PAYROLL GROUP')
)HOME_PAYROLL
ON HOME_PAYROLL.ASSIGNMENT_ID = dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
WHERE
(#p_SELECTED_PERSON_ONLY = 'N' OR EMPLEE.PERSON_ID = #p_PERSON_ID)
AND
(#p_ASGN_STAT_CODE IS NULL OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,1,1)
OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,2,1))
AND
(#p_POLICY_ID IS NULL OR PERSON_ASGN.PROGRAM_CODE = #p_POLICY_ID)
AND
(#p_HOME_COUNTRY_ID IS NULL OR PERSON_ASGN.HOMECOUNTRYID=#p_HOME_COUNTRY_ID)
AND
(#p_HOME_CITY_ID IS NULL OR PERSON_ASGN.HOMECITYID=#p_HOME_CITY_ID )
AND
(#p_HOME_COMPANY_ID IS NULL OR PERSON_ASGN.HOMEBUSINESSID=#p_HOME_COMPANY_ID )
AND
(#p_HOME_DIVISION_ID IS NULL OR PERSON_ASGN.HOMECOMPONENTID=#p_HOME_DIVISION_ID )
AND
(#p_HOST_COUNTRY_ID IS NULL OR PERSON_ASGN.HOSTCOUNTRYID=#p_HOST_COUNTRY_ID )
AND
(#p_HOST_CITY_ID IS NULL OR PERSON_ASGN.HOSTCITYID=#p_HOST_CITY_ID )
AND
(#p_HOST_COMPANY_ID IS NULL OR PERSON_ASGN.HOSTBUSINESSID=#p_HOST_COMPANY_ID )
AND
(#p_HOST_DIVISION_ID IS NULL OR PERSON_ASGN.HOSTCOMPONENTID=#p_HOST_DIVISION_ID )
AND
(#p_CREATED_BY IS NULL OR PERSON_WKS.CREATED_BY=#p_CREATED_BY )
AND
(#p_APPROVED_BY IS NULL OR PERSON_WKS.APPROVED_BY=#p_APPROVED_BY )
AND
(#p_payroll_code IS NULL OR HOME_PAYROLL.VALUE=#p_payroll_code )
ORDER BY PER.LAST_NAME ASC,
PER.FIRST_NAME ASC,
PERSON_WKS.EFFECTIVE_DATE DESC
The Function in the 5th line is the one which is running slow. rest of the part is running in 4secs
The FUNCTION:
BEGIN
DECLARE
#v_ASGN_COUNT INT,
#v_RESULT INT
SELECT #v_ASGN_COUNT = COUNT(ASSIGNMENT_ID) --to find out if this employee has any assignment
FROM ASSIGNMENT
WHERE EXPATRIATE_PERSON_ID = #p_PERSON_ID AND
ASGN_STAT_CODE IN ('PD','A','I')
IF(#v_ASGN_COUNT > 0) --yes assignment, check against SECURITY_ASSIGNMENT_VW
BEGIN
SELECT #v_RESULT = COUNT(ASSIGNMENT_ID)
FROM SECURITY_ASSIGNMENT_VW
WHERE SEC_ACCOUNT_ID = #p_SEC_ACCOUNT_ID AND
ASSIGNMENT_ID IN (SELECT ASSIGNMENT_ID
FROM ASSIGNMENT
WHERE EXPATRIATE_PERSON_ID = #p_PERSON_ID AND
ASGN_STAT_CODE IN ('PD','A','I'))
END
ELSE --no assignment, so check against SECURITY_PERSON_VW
BEGIN
SELECT #v_RESULT = COUNT(PERSON_ID)
FROM SECURITY_PERSON_VW
WHERE SEC_ACCOUNT_ID = #p_SEC_ACCOUNT_ID AND
PERSON_ID = #p_PERSON_ID
END
RETURN #v_RESULT
END
Do the schemas match exactly... in particular check for missing indexes.
Well to begin with you have scalar functions which will run significantly slower as the number of records increase becasue they process row-by-agonizing-row. Not only that you've used the functions in joins which is a horrible practice if you need performance. You have a bunch of OR conditions which tend to slowness. And while it is too hard to actually read the code you posted (please try to format and only use all caps for keywords), I would suspect that some of those conditions are not sargable.
To know what is actually happening check the Execution plan (SQL Server) or Explain Plan (mySQL and others I think) or the equivalent feature in your database. Likely you wil find table scans which of course are going to get significantly slower as the number of records increases.
You may also have a problem with parameter sniffing. Please google to see how to fix that.
One improvement would be to make sure that dbo.FN_GETRPTSSIGNMENTID only gets executed once.
Currently, it gets executed three times.
You can replace two of those calls by joining to the field of the (one) remaing call.
Something like
SELECT WORKSHEET_ID
FROM PERSON PER
INNER JOIN PERSON EMPLEE ON EMPLEE.PERSON_ID = PER.PERSON_ID AND dbo.FN_CHECKRPTSECURITY(EMPLEE.PERSON_ID, #p_SEC_ACCOUNT_ID) > 0
INNER JOIN (
SELECT w1.ASSIGNMENT_ID
, w1.WORKSHEET_ID
, w1.EFFECTIVE_DATE
, w1.APPROVED_BY
, w3.CREATED_BY
FROM WORKSHEET_PAYROLL_VW w1
INNER JOIN WORKSHEET w3 ON w3.WORKSHEET_ID = w1.WORKSHEET_ID
WHERE w1.EFFECTIVE_DATE =
CASE WHEN #p_MOST_RECENT_ONLY = 'Y'
THEN (
SELECT MAX(w2.EFFECTIVE_DATE)
FROM WORKSHEET_PAYROLL_VW w2
WHERE w1.ASSIGNMENT_ID = w2.ASSIGNMENT_ID AND (ISNULL(#p_WKS_EFFECTIVE_DATE,w2.EFFECTIVE_DATE) = w2.EFFECTIVE_DATE)
)
ELSE ISNULL(#p_WKS_EFFECTIVE_DATE,w1.EFFECTIVE_DATE)
END
) PERSON_WKS ON PERSON_WKS.ASSIGNMENT_ID = dbo.FN_GETRPTASSIGNMENTID(EMPLEE.PERSON_ID)
INNER JOIN (
SELECT ASSIGNMENT_ID
, VALUE
FROM ASSIGNMENT_HISTORY AH
WHERE FIELD_NAME ='HOME PAYROLL GROUP'
AND EFFECTIVE_DATE = (
SELECT MAX(EFFECTIVE_DATE)
FROM ASSIGNMENT_HISTORY
WHERE ASSIGNMENT_ID = AH.ASSIGNMENT_ID
AND EFFECTIVE_DATE <=getDate()
AND FIELD_NAME = 'HOME PAYROLL GROUP'
)
LEFT JOIN SEARCH_ASSIGNMENT_VW PERSON_ASGN ON PERSON_ASGN.ASSIGNMENT_ID = PERSON_WKS.ASSIGNMENT_ID
LEFT JOIN LOOKUP EMPLEE_ASGN_STAT ON EMPLEE_ASGN_STAT.TYPE_ = 'ASSIGNMMENT_STATUS_CODE' AND EMPLEE_ASGN_STAT.CODE = PERSON_ASGN.ASGN_STAT_CODE
) HOME_PAYROLL ON HOME_PAYROLL.ASSIGNMENT_ID = PERSON_WKS.ASSIGNMENT_ID
WHERE (#p_SELECTED_PERSON_ONLY = 'N' OR EMPLEE.PERSON_ID = #p_PERSON_ID)
AND (#p_ASGN_STAT_CODE IS NULL OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,1,1) OR PERSON_ASGN.ASGN_STAT_CODE = SUBSTRING(#p_ASGN_STAT_CODE,2,1))
AND (#p_POLICY_ID IS NULL OR PERSON_ASGN.PROGRAM_CODE = #p_POLICY_ID)
AND (#p_HOME_COUNTRY_ID IS NULL OR PERSON_ASGN.HOMECOUNTRYID=#p_HOME_COUNTRY_ID)
AND (#p_HOME_CITY_ID IS NULL OR PERSON_ASGN.HOMECITYID=#p_HOME_CITY_ID )
AND (#p_HOME_COMPANY_ID IS NULL OR PERSON_ASGN.HOMEBUSINESSID=#p_HOME_COMPANY_ID )
AND (#p_HOME_DIVISION_ID IS NULL OR PERSON_ASGN.HOMECOMPONENTID=#p_HOME_DIVISION_ID )
AND (#p_HOST_COUNTRY_ID IS NULL OR PERSON_ASGN.HOSTCOUNTRYID=#p_HOST_COUNTRY_ID )
AND (#p_HOST_CITY_ID IS NULL OR PERSON_ASGN.HOSTCITYID=#p_HOST_CITY_ID )
AND (#p_HOST_COMPANY_ID IS NULL OR PERSON_ASGN.HOSTBUSINESSID=#p_HOST_COMPANY_ID )
AND (#p_HOST_DIVISION_ID IS NULL OR PERSON_ASGN.HOSTCOMPONENTID=#p_HOST_DIVISION_ID )
AND (#p_CREATED_BY IS NULL OR PERSON_WKS.CREATED_BY=#p_CREATED_BY )
AND (#p_APPROVED_BY IS NULL OR PERSON_WKS.APPROVED_BY=#p_APPROVED_BY )
AND (#p_payroll_code IS NULL OR HOME_PAYROLL.VALUE=#p_payroll_code )
ORDER BY
PER.LAST_NAME ASC
, PER.FIRST_NAME ASC
, PERSON_WKS.EFFECTIVE_DATE DESC