【问题标题】:MySQL absentee report scriptMySQL 缺勤报告脚本
【发布时间】:2011-01-07 20:27:48
【问题描述】:

我目前正在尝试编写一个查询,该查询将返回所有未在我们的时间表系统中记录给定日期的时间的用户。我们目前有 2 个表格、时间表和用户。我正在尝试进行一个查询,该查询将返回一个用户列表,这些用户在某个日期范围的时间表表中没有条目。时间表中每天只有一条记录,这应该很简单,但我无法弄清楚如何在我的一生中处理这个问题。

任何帮助将不胜感激:)。

+------------------------+------------------+------ +-----+---------+----------------+ |领域 |类型 |空 |钥匙 |默认 |额外 | +------------------------+------------------+------ +-----+---------+----------------+ |时间表ID | int(11) 无符号 |否 |优先级 |空 |自动增量 | | timesheetForUser | int(11) 无符号 |否 | | | | |时间表ForDate |日期 |否 | | | | |签到时间表 |整数(11) |是 | |空 | | |时间表注释 |正文 |是 | |空 | | |时间表已填写 |小整数(1) |否 | | | | | timesheetNoFillReason | int(11) 无符号 |否 | | | | |时间表CreatedOn |日期时间 |否 | | | | |时间表创建者 | int(11) 无符号 |否 | | | | |时间表UpdatedOn |日期时间 |是 | |空 | | |时间表更新者 | int(11) 无符号 |是 | |空 | | +------------------------+------------------+------ +-----+---------+----------------+ +--------------------------------+--------------+ ------+-----+---------+----------------+ |领域 |类型 |空 |钥匙 |默认 |额外 | +--------------------------------+--------------+ ------+-----+---------+----------------+ |用户名 |整数(11) |否 |优先级 |空 |自动增量 | |用户帐户 |整数(11) |是 | |空 | | |用户组织 |整数(11) |是 | |空 | | |用户是员工 |小整数(4) |是 | | 0 | | | userEmployeeSince |日期 |是 | |空 | | |用户名 | varchar(255) |是 | |空 | | |用户名 | varchar(255) |是 | |空 | | |用户邮箱 | varchar(255) |是 | |空 | | |用户登录 | varchar(50) |是 | |空 | | |用户密码 | varchar(255) |是 | |空 | | |用户发送邀请 |小整数(4) |是 | |空 | | |用户地址1 | varchar(255) |是 | |空 | | |用户地址2 | varchar(255) |是 | |空 | | |用户城市 | varchar(255) |是 | |空 | | |用户国家 |字符(2) |是 | |空 | | |用户状态 | varchar(6) |是 | |空 | | | userState其他 | varchar(255) |是 | |空 | | |用户邮编 | varchar(20) |是 | |空 | | |用户电话 | varchar(50) |是 | |空 | | | user_easypaycode | varchar(6) |是 | |空 | | |用户传真 | varchar(50) |是 | |空 | | |用户单元 | varchar(50) |是 | |空 | | |用户时区 |整数(11) |是 | |空 | | |用户注释 |正文 |是 | |空 | | |用户活动 |小整数(4) |否 | | 0 | | |用户显示图片类型 |小整数(4) |是 | |空 | | |用户显示图片 | varchar(255) |是 | |空 | | |用户缩略图图片 | varchar(255) |是 | |空 | | | userCanWriteMessages |小整数(4) |否 | | 0 | | | userCanWrite评论 |小整数(4) |否 | | 0 | | |用户可上传文件 |小整数(4) |否 | | 0 | | |用户可创建事件 |小整数(4) |否 | | 0 | | | userCanCreateTickets |小整数(4) |否 | | 0 | | | userCanManageProjects |小整数(4) |否 | | 0 | | | userCanManageUsers |小整数(4) |否 | | 0 | | | userCanManageOrganizations |小整数(4) |否 | | 0 | | | userCanManageUserGroups |小整数(4) |否 | | 0 | | | userCanManageMes​​sageCategories |小整数(4) |否 | | 0 | | | userCanManageSetupOptions |小整数(4) |否 | | 0 | | | userCanManageAllUsersItems |小整数(4) |否 | | 0 | | | userCanEnter时间表 |小整数(4) |否 | | | | | userCanManageTimesheets |小整数(4) |否 | | | | | userCanUseTimeclock |小整数(4) |是 | |空 | | | userCanOnlyUseTimeclock |小整数(4) |是 | |空 | | |用户最后登录 |日期时间 |否 | | | | |用户密码重置文本 | varchar(255) |是 | |空 | | |用户已删除 |小整数(4) |否 | | 0 | | |用户删除者 |整数(11) |是 | |空 | | |用户已删除 |日期时间 |是 | |空 | | | userMinHoursPerDay |十进制(10,1) |是 | |空 | | +--------------------------------+--------------+ ------+-----+---------+----------------+

此外,如果一天没有记录时间,则不会在时间表中创建记录。

【问题讨论】:

  • 如果您想要一个无需修改即可工作的答案,您可能需要提供有关您的表结构的更多详细信息。
  • 我应该提到这一点,如果用户在这一天没有任何时间登录,时间表表中将没有记录。
  • @Johnathan:我想我们都猜到了。 :) (相关)列名将是您提出问题的有用信息。你认识他们吗?
  • @Johnathan:感谢您发布时间表的表定义。你可以对 users 表做同样的事情吗?
  • @mark:感谢您的帮助,此查询的理想结果是,对于 timesheetfordate 字段中提到的每一天,我将能够检索在当天的时间表。如果这有任何意义。

标签: php mysql sql join


【解决方案1】:

第一个查询获取所有在@start 和@end 之间没有注册的用户:

SELECT users.userName
FROM users
LEFT JOIN timesheets
ON timesheets.timesheetForUser = users.userID
AND timesheets.timesheetForDate BETWEEN @start AND @end
WHERE timesheets.timesheetForUser IS NULL

此查询获取所有缺少任何日期的用户以及他们缺少哪些日期(正如您在对问题的评论中要求的那样):

SELECT dates.timesheetForDate, users.userName
FROM (SELECT DISTINCT timesheetForDate FROM timesheets) AS dates
CROSS JOIN users
LEFT JOIN timesheets
    ON timesheets.timesheetForUser = users.userID
    AND dates.timesheetForDate = timesheets.timesheetForDate
WHERE timesheets.timesheetForUser IS NULL

试验台:

CREATE TABLE timesheets (timesheetForUser int, timesheetForDate datetime);
INSERT INTO timesheets (timesheetForUser, timesheetForDate) VALUES
(1, '2010-01-01'),
(2, '2010-01-01'),
(3, '2010-01-01'),
(1, '2010-01-02'),
(3, '2010-01-02'),
(2, '2010-01-03'),
(2, '2010-01-04'),
(3, '2010-01-04');

CREATE TABLE users (userId int, userName nvarchar(100));
INSERT INTO users (userId, userName) VALUES
(1, 'Foo'),
(2, 'Bar'),
(3, 'Baz');

使用测试台的第二个查询的输出:

'2010-01-02 00:00:00', 'Bar'
'2010-01-03 00:00:00', 'Foo'
'2010-01-03 00:00:00', 'Baz'
'2010-01-04 00:00:00', 'Foo'

如果您愿意,您还可以将第二个查询创建为视图并像这样查询它:

SELECT * FROM ViewMissingRegistrations
WHERE timesheetForDate BETWEEN @start AND @end

【讨论】:

  • 这不起作用,因为时间表中没有记录没有记录时间的天数。除非我真的误解了 SQL,这也是可能的:S
  • @Jonathan,它使用 LEFT JOIN 这意味着它将为右侧表中的列返回 NULL。它应该可以正常工作,除非我误解了你的问题。
  • @Johnathan:我已更新我的查询以使用您的列名。我还添加了第二个查询来回答您作为对问题的评论而更新的问题。第二个查询还包括一个测试平台,以便您可以在此处看到它的工作原理。
【解决方案2】:
SELECT * FROM Users U
   WHERE U.UserNo NOT IN (
     SELECT timesheetForUser FROM timesheets 
       WHERE timesheetForDate BETWEEN ??? AND ???
   )

【讨论】:

  • 谢谢,这正是我所需要的。我不知何故忘记了mysql可以做子查询:S.
【解决方案3】:

你可以试试

SELECT  u.*
FROM    Users u LEFT JOIN
        timesheets t ON u.userid = t.userid
WHERE   t.Date BETWEEN '01 Jan 2009' AND '31 Jan 2009'
AND     t.userID IS NULL

【讨论】:

  • 我认为这行不通。我认为如果 t.userId 为空,那么 t.DATE 也将为空,所以在我看来,您的 WHERE 子句将始终为假。无论如何,它不会为我在上面发布的测试平台返回任何行(在相应地更改列名之后)。
猜你喜欢
  • 2012-02-27
  • 2012-05-20
  • 1970-01-01
  • 2016-07-20
  • 2022-11-04
  • 1970-01-01
  • 2021-11-25
  • 2020-10-15
  • 1970-01-01
相关资源
最近更新 更多