【问题标题】:Conditional Query for Employee Training Analysis Query员工培训分析查询条件查询
【发布时间】:2011-07-07 03:18:43
【问题描述】:

我需要运行培训查询以返回以下问题的结果:“谁完成了这次培训,但没有完成那次培训?”

在下面的简化表中,我想知道哪个员工已完成 training_id 1(如 completed_date 字段中的日期所示),但尚未完成 training_id 7。

+-------------+-------------+----------------+
| emp_id      | training_id | completed_date |
+-------------+-------------+----------------+
| 1           | 1           | 2010-04-02     |
+-------------+-------------+----------------+
| 1           | 7           | Null           |
+-------------+-------------+----------------+
| 2           | 1           | Null           |
+-------------+-------------+----------------+
| 2           | 7           | Null           |
+-------------+-------------+----------------+

期望的结果是 emp_id 1,我们希望根据查询参数返回他/她完成的训练和未完成的训练:

+-------------+-------------+----------------+
| emp_id      | training_id | completed_date |
+-------------+-------------+----------------+
| 1           | 1           | 2010-04-02     |
+-------------+-------------+----------------+
| 1           | 7           | Null           |
+-------------+-------------+----------------+

我不知道如何使用常规查询来执行此操作,因为它似乎需要 IF 逻辑。例如:返回第一次训练完成的行并返回第二次训练未完成的行,但仅在第一次训练完成时返回。

我如何在 SQL 中表达类似的东西?

【问题讨论】:

    标签: mysql sql conditional


    【解决方案1】:

    您可以使用 EXISTS 子句

    SELECT t.*
    FROM training t
    
    # which employee has completed training_id 1
    WHERE t.training_id = 1 and t.completed_date is not null
    
    #but has not finished training_id 7.
    AND NOT EXISTS (
         SELECT * FROM training t2
         where t2.emp_id=t.emp_id
           and t2.training_id = 7
           and t2.completed_date is not null)
    

    如果你想测试更复杂的东西,比如completed (4,5,6) but not (1,9),那么你可以使用计数:

    SELECT t.emp_id
    FROM training t
    WHERE t.training_id in (4,5,6) and t.completed_date is not null
    group by t.emp_id
    having count(distinct emp_id) = 3
    
    AND NOT EXISTS (
         SELECT * FROM training t2
         where t2.emp_id=t.emp_id
           and t2.training_id in (1,9)
           and t2.completed_date is not null)
    

    最后,如果您需要完整的员工培训记录

    SELECT e.*
    FROM
    (
        SELECT t.emp_id
        FROM training t
        WHERE t.training_id in (4,5,6) and t.completed_date is not null
        group by t.emp_id
        having count(distinct emp_id) = 3
    
        AND NOT EXISTS (
             SELECT * FROM training t2
             where t2.emp_id=t.emp_id
               and t2.training_id in (1,9)
               and t2.completed_date is not null)
    ) search
    inner join training e on e.emp_id = search.emp_id
    order by e.emp_id
    

    【讨论】:

      【解决方案2】:

      您可以在此表上进行自联接(“假设它是两个相同的表并加入它们”):

      SELECT t1.emp_id, t1.training_id, t1.completed_date,
             t2.training_id, t2.completed_date
          FROM training AS t1 /* the aliases are needed for the self-join */
          JOIN training AS t2
              ON t1.emp_id = t2.emp_id
              AND t2.training_id = 7 /* second training  ID */
          WHERE t1.training_id = 1 /* first training ID */
      

      这应该会给你这样的结果:

      t1.emp_id | t1.training_id | t1.completed_date | t2.training_id | t2.completed_date
       1            1               2010-04-02          7                NULL
       2            1               NULL                7                NULL
      

      然后您可以进一步限制 WHERE 查询,例如与

               AND t1.completed_date IS NOT NULL
               AND t2.completed_date IS NULL
      

      这将为您提供所需的集合 - 训练 1 完成,训练 7 未完成。

      【讨论】:

        【解决方案3】:
        select * from training where emp_id in
        (
          select distinct emp_id from training where completed_Date is not null
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-14
          • 2012-05-01
          • 2020-08-21
          相关资源
          最近更新 更多