根据不存在/不存在的 ID 查找记录

Posted

技术标签:

【中文标题】根据不存在/不存在的 ID 查找记录【英文标题】:Find records based on ID which dont/do exist 【发布时间】: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 的参数。 【参考方案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 中没有有效条目的员工。当然,对于表中根本没有记录的员工也是如此。您是否尝试过查询?

以上是关于根据不存在/不存在的 ID 查找记录的主要内容,如果未能解决你的问题,请参考以下文章

thinkphp 根据条件查数据库存在记录则修改 不存在则添加

从一个表中查找另一个表中不存在的记录

Oracle/SQL - 在另一个表中查找或为空或可能不存在或为空的记录

在一个表中查找不存在于另一个表中的ID

HQL 左外连接用于查找一个表中存在而其他表中不存在的记录

索引以查找外键不存在的记录