【问题标题】:Find records based on ID which dont/do exist根据不存在/不存在的 ID 查找记录
【发布时间】:2016-11-01 16:09:18
【问题描述】:

当员工没有时间输入到名为employee_time et 的表中的时间卡中时,我需要报告。

我的问题是找到没有进入该周时间的人。

我使用 NOT IN 来查找表中不存在的员工 ID,因此如果记录不存在,则没有输入时间。这很好用。

Select
     e.userName,
     et.dateStart,
     et.dateEnd

From  employee_time et,
      employee e
Where
      e.employee_id NOT IN (Select employee_id from employee_time
                            where et.dateStart = date and
                                  et.end_date = date)
Group by 
      e.userName,
      et.startDate,
      et.endDate

问题出在应用程序中,当一个人导航到员工时间输入页面时,它会为员工创建一条记录,如果员工没有输入任何时间,则结果是零小时的记录。但该记录现在确实存在。因此在上面的查询中不会找到,我用下面的方法找到了totals = 0的记录

Select
     e.userName,
     et.dateStart,
     et.dateEnd,
     SUM(et.hoursTotal) AS total

From  employee_time et,
      employee e
Where
      e.employee_id = et.employee_id and
      et.hours_total = 0
Group by 
      e.userName,
      et.startDate,
      et.endDate

这也很有效,但是我需要嫁给他们,但迄今为止没有成功。你能帮忙吗?

【问题讨论】:

  • 你想从这两个查询的“联姻”中得到什么实际输出?
  • 您想将hours_total = 0 的记录视为不存在? where hours_total <> 0?
  • 我想要的输出是employee_ids,所以我可以访问用户名并将该人没有输入时间的报告中放置。
  • 很抱歉,但第一个查询太可怕了。你知道你在交叉加入表格,不是吗?如果要显示员工 ID,为什么要显示 dtateStart 和 dateEnd?这些字段应该包含在您的结果中吗?
  • 你说得对,我的交叉联接充当了内部联接,我的日期是我的报告工具 Jasper 的参数。

标签: sql oracle exists


【解决方案1】:

一般格式如下:

Select employee_id
  From employee
Minus
Select employee_id
  From TableExpressionEliminatesOnMissingDates
Minus
Select employee_id
  From TableExpressionEliminatesOnSummarization;

【讨论】:

    【解决方案2】:

    我会这样写:

    Select e.userName
    From employee e
    Where e.employee_id NOT IN (Select employee_id
                                from employee_time
                                where et.dateStart = $date and
                                      et.end_date = $date and 
                                      et.hoursTotal > 0
                               );
    

    您从日期开始作为输入,所以我不明白为什么您在输出中也需要它。如果你这样做,我会选择:

    Select e.userName, w.*
    From employee e cross join
         (select distinct et.dateStart, et.end_date
          from employee_time et
          where $date between et.dateStart and et.dateEnd
         ) w
    Where e.employee_id NOT IN (Select et.employee_id
                                from employee_time et
                                where $date between et.dateStart and et.dateEnd and
                                      et.hoursTotal > 0
                               );
    

    注意:避免在外部查询中使用GROUP BY 会提高性能。

    【讨论】:

      【解决方案3】:
      Select
           e.userName,
           et.dateStart,
           et.dateEnd,
           SUM(et.hoursTotal) AS total
      
      From  
            employee e left outer join employee_time et on (e.employee_id = et.employee_id)
       -- Where nvl(et.hours_total,0) = 0
      Group by 
            e.userName,
            et.startDate,
            et.endDate
      having SUM(et.hoursTotal) > 0
      

      如果你不想让你可以在应该相同的地方使用注释

      如果你只想要employee_ids:

      select e.empolyee_id 
      from employee e left outer join employee_time et on (e.employee_id = et.employee_id)
      Where nvl(et.hours_total,0) = 0;
      

      【讨论】:

        【解决方案4】:

        以下查询查找在给定开始和结束日期的employee_time 中没有有效条目的所有员工:

        select * 
        from employee
        where employee_id not in
        (
          select employee_id 
          from employee_time
          where datestart = :date_start
            and end_date = :date_end
            and hours_total > 0
        );
        

        【讨论】:

        • Thorsten,这是正确的,但我还需要那些从未访问过employee_time 表的人,因此不存在他们的记录。
        • 查询正在查找在给定时间范围内在employee_time 中没有有效条目的员工。当然,对于表中根本没有记录的员工也是如此。您是否尝试过查询?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-24
        • 1970-01-01
        • 2020-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多