复杂的mysql没有返回我需要的结果

0pizxfdo  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(279)

tl:dr我需要从一个表中获取每个雇员最近的一行,并将其与另一个表中每个雇员的多行进行匹配。我可以从一个表中获取每个员工的最新条目,但无法从第二个表中提取数据。
细节:
前两个表显示了我数据库中的一些代表性数据。这里显示的数据和表是我的完整模式和数据集的片段(表:'员工'和'员工工资小时')
员工编号:这是一个id编号,用于标识插入的员工个人编号:这是记录保存到数据库时的日期/时间戳日期时间\u输入:这是员工开始轮班的日期/时间

SELECT employee_number, last_name, inserted_at FROM employees;
TABLE:  employees
+-----------------+-------------+---------------------+
| employee_number |  last_name  | inserted_at         |
+-----------------+-------------+---------------------+
|       123456789 | Lastone     | 2018-02-26 22:26:38 |
|       123456789 | Lastone     | 2018-03-15 15:16:14 |
|       123456789 | Lastone     | 2018-03-15 20:57:23 |
|       123456789 | Lastone     | 2018-04-16 00:10:27 |
|       223456789 | Lasttwo     | 2018-04-16 03:37:49 |
|       270000001 | Lastthree   | 2018-04-06 22:42:50 |
|       270000001 | Lastthree   | 2018-04-17 14:10:01 |
+-----------------+-------------+---------------------+

SELECT employee_number, datetime_in FROM employee_payrollhours
TABLE:  employee_payrollhours
+-----------------+---------------------+
| employee_number | datetime_in         |
+-----------------+---------------------+
|       123456789 | 2018-04-06 08:00:00 |
|       123456789 | 2018-04-08 08:00:00 |
|       123456789 | 2018-04-10 08:00:00 |
|       123456789 | 2018-04-15 08:00:00 |
|       123456789 | 2018-04-17 08:00:00 |
|       123456789 | 2018-04-19 08:00:00 |
|       223456789 | 2018-04-06 08:00:00 |
|       223456789 | 2018-04-08 08:00:00 |
|       223456789 | 2018-04-10 08:00:00 |
|       223456789 | 2018-04-15 08:00:00 |
|       223456789 | 2018-04-17 08:00:00 |
|       223456789 | 2018-04-19 08:00:00 |
|       270000001 | 2018-04-07 08:00:00 |
|       270000001 | 2018-04-09 08:00:00 |
|       270000001 | 2018-04-11 08:00:00 |
|       270000001 | 2018-04-16 08:00:00 |
+-----------------+---------------------+

从员工中为每个员工获取一行

SELECT * FROM employees GROUP BY last_name

并从employees表中获取每个雇员的最新条目。

SELECT * FROM employees e1
WHERE Inserted_at = 
    (SELECT MAX(e2.Inserted_at)
    FROM employees e2
    WHERE e1.Employee_Number = e2.Employee_Number)
+-----------------+-------------+---------------------+
| employee_number |  last_name  | inserted_at         |
+-----------------+-------------+---------------------+
|       123456789 | Lastone     | 2018-04-16 00:10:27 |
|       223456789 | Lasttwo     | 2018-04-16 03:37:49 |
|       270000001 | Lastthree   | 2018-04-17 14:10:01 |
+-----------------+-------------+---------------------+

这就是我想要的。我希望“employees”中每个员工的最新条目与“employee\u payrollhours”表中相应的员工数据一起显示。

+-------------------+---------------------+
|     last_name     | datetime_in         |
+-------------------+---------------------+
|       Lastone     | 2018-04-06 08:00:00 |
|       Lastone     | 2018-04-08 08:00:00 |
|       Lastone     | 2018-04-10 08:00:00 |
|       Lastone     | 2018-04-15 08:00:00 |
|       Lastone     | 2018-04-17 08:00:00 |
|       Lastone     | 2018-04-19 08:00:00 |
|       Lasttwo     | 2018-04-06 08:00:00 |
|       Lasttwo     | 2018-04-08 08:00:00 |
|       Lasttwo     | 2018-04-10 08:00:00 |
|       Lasttwo     | 2018-04-15 08:00:00 |
|       Lasttwo     | 2018-04-17 08:00:00 |
|       Lasttwo     | 2018-04-19 08:00:00 |
|       Lastthree   | 2018-04-07 08:00:00 |
|       Lastthree   | 2018-04-09 08:00:00 |
|       Lastthree   | 2018-04-11 08:00:00 |
|       Lastthree   | 2018-04-16 08:00:00 |
+-------------------+---------------------+

这个查询给我错误“subquery返回超过1行”

SELECT employees.*, employee_payrollhours.*
FROM employees, employee_payrollhours
WHERE employee_payrollhours.employee_number = (select employee_number from employees group by last_name);

这个查询给了我混淆的数据。

SELECT employees.last_name, employees.employee_number, employee_payrollhours.employee_number, employee_payrollhours.datetime_in
FROM employees, employee_payrollhours
WHERE employee_payrollhours.employee_number = employees.employee_number;

这个查询没有返回结果

SELECT * FROM employees e1, employee_payrollhours
WHERE `e1`.`Inserted_at` = 
    (SELECT MAX(e2.Inserted_at)
    FROM employees e2
    WHERE e1.Employee_Number = e2.Employee_Number)
    AND (`e1`.`Inserted_at` = 
    (SELECT MAX(e2.Inserted_at)
    FROM employees e2
    WHERE e1.Employee_Number = e2.Employee_Number)) = employee_payrollhours.Employee_Number;

有人能给我一些指导,如何处理这个问题,找到我需要的查询?
先谢谢你。

fivyi3re

fivyi3re1#

当然有很多方法,我只介绍其中一种。这里的诀窍是通过 inserted_atemployees table。一种方法当然是做一个 group by 查询方式 max ,但那我们就不能加入 employee_payrollhours table。然而,我们可以使用一个技巧,如果我们做一个 left outer joinemployees 就其自身而言,作为有更大 inserted_at 然后只过滤连接为null的记录,这将给我们相同的结果 group by 但我们仍然可以加入 employee_payrollhours 得到想要的结果。
这样地:

select e1.*, eprh.* from employees e1
  left outer join employees e2 on
    e1.employee_number = e2.employee_number and
    e2.inserted_at > e1.inserted_at
  left join employees_payrollhours eprh on
    eprh.employee_number = e1.employee_number
where e2.employee_number is null
rjee0c15

rjee0c152#

我认为这个查询(sqlfiddle)可以满足您的需要:

select e.last_name, e.most_recent, p.datetime_in
from (select employee_number, last_name, max(inserted_at) as most_recent from employees group by employee_number) e
left join employee_payrollhours p
on p.employee_number = e.employee_number

输出:

last_name   most_recent             datetime_in
Lastone     2018-04-16 00:10:27     2018-04-06 08:00:00
Lastone     2018-04-16 00:10:27     2018-04-08 08:00:00
Lastone     2018-04-16 00:10:27     2018-04-10 08:00:00
Lastone     2018-04-16 00:10:27     2018-04-15 08:00:00
Lastone     2018-04-16 00:10:27     2018-04-17 08:00:00
Lastone     2018-04-16 00:10:27     2018-04-19 08:00:00
Lasttwo     2018-04-16 03:37:49     2018-04-06 08:00:00
Lasttwo     2018-04-16 03:37:49     2018-04-08 08:00:00
Lasttwo     2018-04-16 03:37:49     2018-04-10 08:00:00
Lasttwo     2018-04-16 03:37:49     2018-04-15 08:00:00
Lasttwo     2018-04-16 03:37:49     2018-04-17 08:00:00
Lasttwo     2018-04-16 03:37:49     2018-04-19 08:00:00
Lastthree   2018-04-17 14:10:01     2018-04-07 08:00:00
Lastthree   2018-04-17 14:10:01     2018-04-09 08:00:00
Lastthree   2018-04-17 14:10:01     2018-04-11 08:00:00
Lastthree   2018-04-17 14:10:01     2018-04-16 08:00:00
voase2hg

voase2hg3#

感谢你们两位(截至本文撰写之时)的及时回复。我显然需要更多的练习。
在评论中,我解释了为什么我选择了这个答案。
我在应用程序中尝试了这两种解决方案。我选择的那个允许那些没有进入任何时间的员工仍然被显示。这包括在特定时间段内可能没有工作的兼职员工,这些员工仍将显示在结果中。

相关问题