Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检索SQL查询中的第一个True条件_Sql_Oracle_Oracle11g - Fatal编程技术网

检索SQL查询中的第一个True条件

检索SQL查询中的第一个True条件,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我遇到了一个问题,我需要根据具体情况获得员工的变动 我应该仅根据以下更改检索行: 作业类别(仅基于表xxtest中显示的特定类别) 工资基础(仅从小时到工薪,反之亦然,也见表xxtest) 支付基础和分配类别(基于上述相同的约束条件) 我创建了一个表(XXTEST)来限制SQL只引用这个映射(请参见问题末尾的DML和DDL) 基本上,我期望的数据是: | --------|-------------------|------------------|---------------|-------

我遇到了一个问题,我需要根据具体情况获得员工的变动

我应该仅根据以下更改检索行:

  • 作业类别(仅基于表xxtest中显示的特定类别)
  • 工资基础(仅从小时到工薪,反之亦然,也见表xxtest)
  • 支付基础和分配类别(基于上述相同的约束条件)
  • 我创建了一个表(XXTEST)来限制SQL只引用这个映射(请参见问题末尾的DML和DDL)

    基本上,我期望的数据是:

    | --------|-------------------|------------------|---------------|------------- |-------------|
    | Sample  | FROM_PAY_BASIS_ID | TO_PAY_BASIS_ID  | FROM_CATEGORY | TO_CATEGORY  | CHANGE_TYPE |
    | --------| ------------------| -----------------| --------------|------------- |-------------|
    | 1       | 1                 | 2                | FR            | FR           | PAY_BASIS   |
    | 2       | 1                 | 1                | FT            | FR           | ASSIGN_CAT  |
    | 3       | 1                 | 2                | FT            | FR           | BOTH        |
    
    上表基于以下条件:

    1. if BOTH, it should get "Assignment Category and Pay Basis" as its Change_Type
    2. if Assignment Category, it should get "Assignment Category" as its Change_Type
    3. if Pay Basis, it should get "Pay Basis" as its Change_Type 
    
    我希望它首先计算条件1,如果为false,则计算下一个直到最后一个。
    当这两列都更改时,会出现问题,导致3+行的更改类型为“PAY\u BASIS”、“ASSIGN\u CAT”、“both”作为值

    我尝试了很多方法,但似乎没有什么能完全满足我的需要,例如下面的查询:

    select  *
    from    (select coalesce((select  CHANGE_TYPE
                              from    XXTEST  
                              where   FROM_CATEGORY   = pax.EMPLOYMENT_CATEGORY    
                              AND     TO_CATEGORY     = pax2.EMPLOYMENT_CATEGORY
                              AND     FROM_ID         = pax.PAY_BASIS_ID
                              and     TO_ID           = pax2.PAY_BASIS_ID),
                              select  CHANGE_TYPE
                              from    XXTEST  
                              WHERE   FROM_CATEGORY   = pax.EMPLOYMENT_CATEGORY    
                              AND     TO_CATEGORY     = pax2.EMPLOYMENT_CATEGORY
                              AND     FROM_ID         = 0
                              and     TO_ID           = 0),
                              select  CHANGE_TYPE
                              from    XXTEST  
                              WHERE   FROM_CATEGORY   = 'N/A'
                              AND     TO_CATEGORY     = 'N/A'
                              AND     FROM_ID         = pax.PAY_BASIS_ID
                              and     TO_ID           = pax2.PAY_BASIS_ID),
                              NULL ) CHANGE_TYPE FROM DUAL ) CHANGE_TYPE
                ,   PPX.FULL_NAME
                ,   PPX.EMPLOYEE_NUMBER
            from    per_people_X          ppx
                ,   per_assignments_X     pax 
                ,   per_assignments_X     pax2
            WHERE   pax.assignment_id     = pax2.assignment_id
            AND     PPX.PERSON_id         = pax2.PERSON_id
            AND     PPX.PERSON_id         = PAX.PERSON_id)
    where   CHANGE_TYPE is not null;
    
    这种方法可以工作,但它会检索所有记录,不管它是否匹配(由于NULL“else”条件),并导致Change_Type=NULL。 是否可以只过滤那些没有Change_Type=NULL的记录,而不将其封装在另一个SELECT语句中

    我也试过用CASE, 如果员工的薪资基础ID仅更改(例如从1更改为2),则可以正常工作 如果只有员工的类别发生了变化(例如从FT到FR), 但只要“两个”更改都发生,它就会评估所有情况(返回3行)


    有什么建议吗?

    您可能在where子句中的case语句后面,例如:

    SELECT  PPX.FULL_NAME
        ,   PPX.EMPLOYEE_NUMBER
        ,   XT.CHANGE_TYPE
    FROM    per_people_X          ppx
        ,   XXTEST                XT
        ,   per_assignments_X     pax 
        ,   per_assignments_X     pax2
    WHERE   pax.assignment_id     = pax2.assignment_id
    AND     PPX.PERSON_id         = pax2.PERSON_id
    AND     PPX.PERSON_id         = PAX.PERSON_id
    AND     (-- Both Employment Category and Pay Basis records records that were Changed
             case when     XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
                       AND XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
                       AND XT.FROM_ID       = pax.PAY_BASIS_ID           
                       AND XT.TO_ID         = pax2.PAY_BASIS_ID
                       then 1
                  else 0
             end = 1
             OR
             -- all Pay Basis records that were "Updated"
             case when     XT.FROM_CATEGORY = 'N/A'
                       AND XT.TO_CATEGORY   = 'N/A'
                       AND XT.FROM_ID       = pax.PAY_BASIS_ID           
                       AND XT.TO_ID         = pax2.PAY_BASIS_ID
                       then 1
                  else 0
             end = 1
             OR
             -- all Assignment Category records that were "Updated"
             case when     XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
                       AND XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
                       AND XT.FROM_ID       = 0       
                       AND XT.TO_ID         = 0
                       then 1
                  else 0
             end = 1);
    
    注意:未测试,因为您没有提供per_people_x或per_assignments表的示例数据


    您可能需要在“两个类别”的大小写表达式中添加额外的条件,以排除其他两种情况;从您目前提供的数据来看,这并不明显。

    首先,如果您使用或应该使用括号
    和(…或…
    ,或者您丢失了一些谓词。您的第一个查询应重写为:

    SELECT  PPX.FULL_NAME
    ,   PPX.EMPLOYEE_NUMBER
    ,   XT.CHANGE_TYPE
    FROM    per_people_X          ppx
    ,   XXTEST                XT
    ,   per_assignments_X     pax 
    ,   per_assignments_X     pax2
    WHERE   pax.assignment_id     = pax2.assignment_id
    AND     PPX.PERSON_id         = pax2.PERSON_id
    AND     PPX.PERSON_id         = PAX.PERSON_id
    -- THIS IS THE SECTION OF THE QUERY WHERE I'M HAVING PROBLEMS -- 
    -- Both Employment Category and Pay Basis records records that were Changed
    AND ( 
         (XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
        AND      XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
        AND      XT.FROM_ID       = pax.PAY_BASIS_ID           
        AND      XT.TO_ID         = pax2.PAY_BASIS_ID)
        -- all Pay Basis records that were "Updated"
        or      (XT.FROM_CATEGORY = 'N/A'
        AND      XT.TO_CATEGORY   = 'N/A'
        AND      XT.FROM_ID       = pax.PAY_BASIS_ID           
        AND      XT.TO_ID         = pax2.PAY_BASIS_ID)
        -- all Assignment Category records that were "Updated"
        or      (XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
        AND      XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
        AND      XT.FROM_ID       = 0       
        AND      XT.TO_ID         = 0)
    );
    
    编辑:添加具有条件排名的解决方案

    SELECT FULL_NAME
    ,   EMPLOYEE_NUMBER
    ,   CHANGE_TYPE
    FROM (
    SELECT  PPX.FULL_NAME
    ,   PPX.EMPLOYEE_NUMBER
    ,   XT.CHANGE_TYPE
    ,   DENSE_RANK() OVER (PRTITION BY PPX.PERSON_id,pax.assignment_id ORDER BY
       CASE WHEN XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
                 AND      XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
                 AND      XT.FROM_ID       = pax.PAY_BASIS_ID           
                 AND      XT.TO_ID         = pax2.PAY_BASIS_ID 
            THEN 1
            WHEN XT.FROM_CATEGORY = 'N/A'
                 AND      XT.TO_CATEGORY   = 'N/A'
                 AND      XT.FROM_ID       = pax.PAY_BASIS_ID           
                 AND      XT.TO_ID         = pax2.PAY_BASIS_ID
            THEN 2
            ELSE 3 
        END
        ) as RNK
    FROM    per_people_X          ppx
    ,   XXTEST                XT
    ,   per_assignments_X     pax 
    ,   per_assignments_X     pax2
    WHERE   pax.assignment_id     = pax2.assignment_id
    AND     PPX.PERSON_id         = pax2.PERSON_id
    AND     PPX.PERSON_id         = PAX.PERSON_id
    -- THIS IS THE SECTION OF THE QUERY WHERE I'M HAVING PROBLEMS -- 
    -- Both Employment Category and Pay Basis records records that were Changed
    AND ( 
         (XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
        AND      XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
        AND      XT.FROM_ID       = pax.PAY_BASIS_ID           
        AND      XT.TO_ID         = pax2.PAY_BASIS_ID)
        -- all Pay Basis records that were "Updated"
        or      (XT.FROM_CATEGORY = 'N/A'
        AND      XT.TO_CATEGORY   = 'N/A'
        AND      XT.FROM_ID       = pax.PAY_BASIS_ID           
        AND      XT.TO_ID         = pax2.PAY_BASIS_ID)
        -- all Assignment Category records that were "Updated"
        or      (XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY    
        AND      XT.TO_CATEGORY   = pax2.EMPLOYMENT_CATEGORY
        AND      XT.FROM_ID       = 0       
        AND      XT.TO_ID         = 0)
    )
    ) WHERE RNK = 1;
    

    我没有关注你帖子的所有细节、答案和随后的评论,但似乎你可能想要这样的东西。为了在所有情况下都得到一个确切的答案,您可能需要一个
    CASE
    表达式。在下面的代码中,我使用嵌套的
    CASE
    表达式,但这只是为了节省键入时间(和一点执行时间);可以使用一个
    大小写
    表达式
    重写它

    这样做的原因是,
    中的第一个真实条件出现时,计算立即结束。。。然后找到了…
    对。您必须弄清楚如何将其附加到现有查询中——我只是将其输出放在CTE中,以便在下面进行测试

    with
         query_output ( empl_id, from_pay_basis_id, to_pay_basis_id, from_category, to_category ) as (
           select 101, 1, 2, 'FR', 'FR' from dual union all
           select 102, 1, 1, 'FT', 'FR' from dual union all
           select 103, 1, 2, 'FT', 'FR' from dual union all
           select 104, 1, 1, 'FR', 'FR' from dual
         )
    select empl_id, from_pay_basis_id, to_pay_basis_id, from_category, to_category,
           case when from_category != to_category then
                     case when from_pay_basis_id != to_pay_basis_id then 'Assignment Category and Pay Basis'
                          else                                     'Assignment Category'
                     end
                when from_pay_basis_id != to_pay_basis_id then 'Pay Basis'
           end as change_type
    from   query_output;
    
    EMPL_ID FROM_PAY_BASIS_ID   TO_PAY_BASIS_ID FROM_CATEGORY   TO_CATEGORY CHANGE_TYPE
    ------- ----------------- --------------- ------------- ----------- ---------------------------------
    101                     1               2 FR            FR          Pay Basis
    102                     1               1 FT            FR          Assignment Category
    103                     1               2 FT            FR          Assignment Category and Pay Basis
    104                     1               1 FR            FR
    

    Hi@michael-piankov,很遗憾,这不起作用。分配类别分配类别分配类别和薪资基础分配类别和薪资基础BasisHi@michael-piankov,不幸的是,这不起作用。它返回了所有更改类型值:“分配类别”“分配类别和支付基础”“支付基础”,据我所知,如果通过了第一条规则,则不应显示下一条规则。我添加了解决方案嗨@michael piankov,我会检查一下,但是从外观上看,这不是我想要的。你能解释清楚你到底需要什么吗?这是查询订单条件,对于任何PPX.PERSON\u id和pax.assignment\u id,只返回一个。您需要什么?嗨@boneist,也没有运气。这不起作用。它还返回了所有更改类型值:“分配类别”“分配类别和支付基础”“支付基础”@MigsIsip请更新您的问题,以包括其他表的示例数据以及您期望的输出。这样,我们就可以处理查询以获得正确答案。您好@Boneist,我已经用DML和DDL数据更新了问题。@MigsIsip您已经为XXTEST表添加了数据。但是,这不是查询中使用的唯一表。既然我们不是坐在你旁边,我们怎么能运行这个查询呢?请更新问题,以提供其他两个表的样本数据(以及该样本数据的预期输出)-每个人和每个分配。请记住,示例越明确,因为表单中的字符限制,我似乎无法完全发布DML和DDL。如何将其附加为文件@boneistThanks@mathguy,我从来没有想过嵌套案例!我只做了一个直接的
    code
    当…然后…
    code
    时,没有嵌套它,类似于IF语句。让我检查一下,然后再给你回复。仔细想想,这方面的限制是我必须硬编码更改类型,我正试图避免这种情况( @mathguy@MigsIsip我不知道你的意思,我只能猜测。你希望更改类型是动态的(在运行时获取列名)吗?在这个线程中没有提到这一点,或者我错过了。如果这是您想要的,那么您可以启动一个不同的线程,因为这是一个完全不同类型的问题-它将需要动态SQL。