开发者社区 问答 正文

NULL尽管存在值,但仍会产生值

将查询更改为新建议,并遇到另一个问题,因此以NEW POST的形式发布

我创建了以下查询,为表中不存在薪资操作类型PAY_PAYROLL_ACTIONS 或action_type为'Q','R'的那些雇员提供结果。

现在,下面的查询返回一个特定雇员的值,但同时返回null和'Q','R'。现在,如果员工在某个特定日期的值为“ Q”或“ R”,那么它又如何返回null?

在此处输入图片说明

我需要在下面的查询中添加一个条件,以便如果某个员工有ACTION_TYPE_code“ Q”,“ R”,则它不会变为NULL条件。

即对于上述雇员,由于查询已获取action_type不为636,因此不应该返回NULL action_type ...

仅当ACTION_TYPE IS NULL在那个特定日期且没有其他值时才应返回

select * from (SELECT DISTINCT PAPF.PERSON_NUMBER, NAME.FIRST_NAME, NAME.LAST_NAME, PAAM.ASSIGNMENT_NUMBER, PY.PAYROLL_NAME, PPA.ACTION_TYPE ACTION_TYPE_code, ( SELECT MEANING FROM FND_LOOKUP_VALUES WHERE LOOKUP_TYPE = 'ACTION_TYPE' AND LOOKUP_CODE = PPA.ACTION_TYPE AND LANGUAGE = 'US' AND ENABLED_FLAG = 'Y' ) ACTION_TYPE, TO_CHAR(PPA.EFFECTIVE_DATE, 'DD-MON-YYYY') EFFECTIVE_DATE, PPA.PAYROLL_ACTION_ID ACTION_NUMBER, PCS.CONSOLIDATION_SET_NAME, TO_CHAR(FINC, 'DD-MON-YYYY') FINC, PASV.USER_STATUS FROM PAY_ASSIGNED_PAYROLLS_DN PAPD JOIN PAY_PAYROLL_TERMS PT ON ( PAPD.PAYROLL_TERM_ID = PT.PAYROLL_TERM_ID ) JOIN PAY_PAY_RELATIONSHIPS_DN PR ON ( PT.PAYROLL_RELATIONSHIP_ID = PR.PAYROLL_RELATIONSHIP_ID ) JOIN PAY_ALL_PAYROLLS_F PY ON ( PAPD.PAYROLL_ID = PY.PAYROLL_ID ) JOIN PER_ALL_PEOPLE_F PAPF ON ( PR.PERSON_ID = PAPF.PERSON_ID ) JOIN PAY_CONSOLIDATION_SETS PCS ON ( PCS.CONSOLIDATION_SET_ID = PY.CONSOLIDATION_SET_ID ) JOIN PER_PERSON_NAMES_F NAME ON ( PAPF.PERSON_ID = NAME.PERSON_ID ) JOIN PAY_REL_GROUPS_DN PAYREL ON ( PAYREL.PARENT_REL_GROUP_ID = PAPD.PAYROLL_TERM_ID ) JOIN PER_ALL_ASSIGNMENTS_M PAAM ON ( PAYREL.ASSIGNMENT_ID = PAAM.ASSIGNMENT_ID ) JOIN PAY_PAYROLL_REL_ACTIONS PPRA ON ( PPRA.PAYROLL_RELATIONSHIP_ID = PR.PAYROLL_RELATIONSHIP_ID ) JOIN PER_ASSIGNMENT_STATUS_TYPES_VL PASV ON ( PASV.ASSIGNMENT_STATUS_TYPE_ID = PAAM.ASSIGNMENT_STATUS_TYPE_ID ) JOIN PER_LEGISLATIVE_DATA_GROUPS_VL LDG ON ( LDG.LEGISLATION_CODE = PAAM.LEGISLATION_CODE ) LEFT JOIN PAY_PAYROLL_ACTIONS PPA ON ( PPA.PAYROLL_ID = PY.PAYROLL_ID AND PPA.PAYROLL_ACTION_ID = PPRA.PAYROLL_ACTION_ID -- TEJASH : SUGGESTION-1 : ADDED FOLLOWING CONDITIONS IN JOIN CONDITIONS INSTEAD OF WHERE CLAUSE -- AND PPA.ACTION_TYPE IS NULL -- CHANGED FOLLOWING CONDITION TO USE DATES RATHER THAN CHAR AND NVL(PPA.EFFECTIVE_DATE, DATE '2019-09-01') BETWEEN DATE '2019-09-01' AND DATE '2019-12-01' AND PPA.CONSOLIDATION_SET_ID = PCS.CONSOLIDATION_SET_ID AND NVL(PPA.EFFECTIVE_DATE,trunc(sysdate)) BETWEEN PAYREL.START_DATE AND PAYREL.END_DATE AND NVL(PPA.EFFECTIVE_DATE,trunc(sysdate)) BETWEEN PAPD.START_DATE AND PAPD.END_DATE ) -- TEJASH : SUGGESTION-2 : USE LEFT JOIN HERE LEFT JOIN PAY_TIME_PERIODS PTP ON ( PPA.EARN_TIME_PERIOD_ID = PTP.TIME_PERIOD_ID AND PTP.PAYROLL_ID = PY.PAYROLL_ID ) WHERE 1 = 1

AND PAAM.ASSIGNMENT_TYPE = 'E' 
   --ADDED condition---    
AND PASV.USER_STATUS LIKE '%Payroll Eligible'
AND ( FINC > PTP.START_DATE
      OR FINC IS NULL )

-- COMMENTED BY TEJASH -- AND ( PPA.ACTION_TYPE IS NULL -- OR ppa.action_type IN ( 'Q', 'R' ) -- ) -- AND ldg.name = Nvl(:P_LEGISLATIVE_GROUP, ldg.name)
--AND pasv.user_status = Nvl(:P_ASSIGNMENT_STATUS,
-- pasv.user_status)
-- COMMENTED BY TEJASH --AND TO_CHAR(NVL(PPA.EFFECTIVE_DATE, '2019-09-01'), 'YYYY-MM-DD') BETWEEN ( '2019-09-01' ) AND ( '2019-12-01' ) -------
--AND PPA.CONSOLIDATION_SET_ID = PCS.CONSOLIDATION_SET_ID AND PAYREL.GROUP_TYPE = 'A' AND NAME.NAME_TYPE = 'GLOBAL' --AND NVL(PPA.EFFECTIVE_DATE, TRUNC(SYSDATE)) BETWEEN PAYREL.START_DATE AND PAYREL.END_DATE --AND NVL(PPA.EFFECTIVE_DATE, TRUNC(SYSDATE)) BETWEEN PAPD.START_DATE AND PAPD.END_DATE AND TRUNC(SYSDATE) BETWEEN PAPF.EFFECTIVE_START_DATE AND PAPF.EFFECTIVE_END_DATE AND TRUNC(SYSDATE) BETWEEN PY.EFFECTIVE_START_DATE AND PY.EFFECTIVE_END_DATE AND TRUNC(SYSDATE) BETWEEN PAAM.EFFECTIVE_START_DATE AND PAAM.EFFECTIVE_END_DATE AND TRUNC(SYSDATE) BETWEEN NAME.EFFECTIVE_START_DATE AND NAME.EFFECTIVE_END_DATE ) where (ACTION_TYPE_code is null or ACTION_TYPE_code in ('Q','R'))

展开
收起
保持可爱mmm 2019-11-18 14:39:25 536 分享 版权
阿里云 AI 助理回答

根据您的描述,您希望调整SQL查询以确保当员工在特定日期有ACTION_TYPE为'Q'或'R'时,不返回ACTION_TYPE为NULL的结果。从您提供的查询中,可以看到您已经尝试通过LEFT JOIN和WHERE子句来实现这一逻辑,但似乎还存在一些问题导致不符合预期的输出。

为了更精确地达到您的需求,我建议对查询进行如下修改:

  1. 保持LEFT JOIN:对于PAY_PAYROLL_ACTIONS PPA的连接,继续使用LEFT JOIN以包含所有员工记录,即使它们在PAY_PAYROLL_ACTIONS表中没有匹配项。
  2. 条件移至WHERE子句:将过滤ACTION_TYPE为NULL或'Q'、'R'的条件放在WHERE子句的合适位置,并且明确排除那些ACTION_TYPE既不是NULL也不是'Q'、'R'的情况。
  3. 处理日期范围:确保日期范围的比较正确无误,特别是与时间周期(PAY_TIME_PERIODS)相关的条件。

基于以上考虑,您可以尝试以下调整后的查询部分:

...
LEFT JOIN PAY_PAYROLL_ACTIONS PPA 
ON ( 
    PPA.PAYROLL_ID = PY.PAYROLL_ID 
    AND PPA.PAYROLL_ACTION_ID = PPRA.PAYROLL_ACTION_ID
    AND NVL(PPA.EFFECTIVE_DATE, trunc(sysdate)) BETWEEN PAYREL.START_DATE AND PAYREL.END_DATE
    AND NVL(PPA.EFFECTIVE_DATE,trunc(sysdate)) BETWEEN PAPD.START_DATE AND PAPD.END_DATE
)
WHERE 
    PAAM.ASSIGNMENT_TYPE = 'E' 
    AND PASV.USER_STATUS LIKE '%Payroll Eligible'
    AND (
        FINC > COALESCE(PTP.START_DATE, DATE '9999-12-31') -- Assuming a far future date if PTP.START_DATE is NULL
        OR FINC IS NULL
    )
    AND (
        ACTION_TYPE_code IS NULL 
        OR ACTION_TYPE_code IN ('Q', 'R')
    )
    AND NOT EXISTS (
        SELECT 1 
        FROM PAY_PAYROLL_ACTIONS PPA_inner 
        WHERE 
            PPA_inner.PAYROLL_ID = PY.PAYROLL_ID 
            AND PPA_inner.PERSON_ID = PAPF.PERSON_ID
            AND PPA_inner.ACTION_TYPE NOT IN ('Q', 'R')
            AND NVL(PPA_inner.EFFECTIVE_DATE, trunc(sysdate)) = NVL(PPA.EFFECTIVE_DATE, trunc(sysdate))
    )
...

这里的关键更改是添加了一个NOT EXISTS子句,用于排除那些在相同日期有非'Q'或'R' ACTION_TYPE的员工记录。这应该能解决您提到的问题,即如果一个员工在某个特定日期有'Q'或'R'的ACTION_TYPE,则不应再考虑其ACTION_TYPE为NULL的情况。

请注意,这个解决方案假设了每个员工每天最多只有一条ACTION_TYPE记录。如果有多个ACTION_TYPE记录可能适用于同一天的同一员工,那么您可能需要进一步细化此逻辑以准确反映业务规则。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: