我正在使用以下查询来获取两个给定日期之间的日期列表:
SELECT selected_date FROM
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
WHERE selected_date BETWEEN '2016-03-08' AND '2016-03-11';
Run Code Online (Sandbox Code Playgroud)
这给了我以下输出:
+---------------+
| selected_date |
+---------------+
| 2016-03-08 |
| 2016-03-09 |
| 2016-03-10 |
| 2016-03-11 |
+---------------+
Run Code Online (Sandbox Code Playgroud)
以下查询为我提供了在特定日期工作所需的所有员工的列表:
SELECT employee.id, employee.firstname
FROM Users employee
LEFT JOIN Table1 table1 ON table1.fId = employee.tId
WHERE table1.day = dayofweek('2016-03-10')
Run Code Online (Sandbox Code Playgroud)
这产生:
+----+-----------+
| id | firstname |
+----+-----------+
| 1 | Mat |
| 2 | Tom |
+----+-----------+
Run Code Online (Sandbox Code Playgroud)
如果没有员工需要在给定日期工作,则结果为空。
我有一个第三个表,其中列出了每个员工在某一天的表现:
SELECT * FROM performance;
+----+------------+------------+------+
| id | employeeId | date | val |
+----+------------+------------+------+
| 1 | 1 | 2016-03-08 | 100 |
| 2 | 2 | 2016-03-08 | 90 |
| 3 | 1 | 2016-03-09 | 80 |
| 4 | 2 | 2016-03-09 | 100 |
+----+------------+------------+------+
Run Code Online (Sandbox Code Playgroud)
我想加入以上三个结果以产生:
+----+------------+-----------+------------+------+
| id | employeeId | firstname | date | val |
+----+------------+-----------+------------+------+
| 1 | 1 | Mat | 2016-03-08 | 100 |
| 2 | 2 | Tom | 2016-03-08 | 90 |
| 3 | 1 | Mat | 2016-03-09 | 80 |
| 4 | 2 | Tom | 2016-03-09 | 100 |
| 5 | 1 | Mat | 2016-03-10 | null |
| 6 | 2 | Tom | 2016-03-10 | null |
+----+------------+-----------+------------+------+
Run Code Online (Sandbox Code Playgroud)
注意:打开2016-03-10 Mat并且Tom不需要工作。因此,它们的值在最终结果中应该为空。在这种情况下,该performance表将没有 Mat 和 Tom 的条目2016-03-10。
我对如何实现这一目标有点迷茫。
你必须CROSS JOIN在Users你的日历查询表。
它将为您提供每个用户的每个日期之一的结果:
selected_date | firstname
2016-03-08 | Mat
2016-03-09 | Mat
2016-03-10 | Mat
2016-03-11 | Mat
2016-03-08 | Tom
2016-03-09 | Tom
2016-03-10 | Tom
2016-03-11 | Tom
Run Code Online (Sandbox Code Playgroud)
这然后可以LEFT JOIN与Performance表。( SQL 小提琴)
SELECT u.id, u.firstname, cal.selected_date, p.val
FROM Users u
CROSS JOIN (
SELECT selected_date FROM (
SELECT adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date
from
(SELECT 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(SELECT 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(SELECT 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(SELECT 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(SELECT 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4
) v
WHERE selected_date BETWEEN '2016-03-08' AND '2016-03-11'
) cal
LEFT JOIN performance p
ON u.id = p.employeeId AND cal.selected_date = p.date;
Run Code Online (Sandbox Code Playgroud)
id | firstname | selected_date | val
1 | Mat | 2016-03-08 | 100
2 | Tom | 2016-03-08 | 90
1 | Mat | 2016-03-09 | 80
2 | Tom | 2016-03-09 | 100
1 | Mat | 2016-03-10 | (null)
2 | Tom | 2016-03-10 | (null)
1 | Mat | 2016-03-11 | (null)
2 | Tom | 2016-03-11 | (null)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1796 次 |
| 最近记录: |