我有下表
worker_log
:
日志日期 | total_workers | 商店 |
---|---|---|
2021-01-01 | 2 | 拉尔夫斯 |
2021-02-01 | 0 | 拉尔夫斯 |
2021-03-01 | 3 | 拉尔夫斯 |
2021-01-01 | 3 | 本尼的 |
2021-02-01 | 0 | 本尼的 |
2021-03-01 | 1 | 本尼的 |
添加有关如何阅读上表的其他上下文:
对于 Ralphs,从 1/1/21 到 1/31/21,总共有 2 个工人。从 2/1 到 2/28/21,共有 0 个工人。所以在 2/1/21,worker 数量从 2 变为 0。从 3/1/21 到现在,共有 3 个 worker。所以在 21 年 3 月 1 日,工人数量从 0 变为 3。
我有以下名为
request_log
的临时表:
ticket_no | 请求日期 | 商店 |
---|---|---|
10000 | 2021-01-03 | 拉尔夫斯 |
10001 | 2021-01-08 | 拉尔夫斯 |
10002 | 2021-02-05 | 拉尔夫斯 |
10003 | 2021-04-03 | 拉尔夫斯 |
10004 | 2021-01-21 | 本尼的 |
10005 | 2021-02-23 | 本尼的 |
10006 | 2021-04-03 | 本尼的 |
我需要创建另一个表,称为
requests
,它显示是否在特定日期请求了请求票,是否有基于 log_date
列 worker_log
表的工作人员。 requests
表的最终结果应该是这样的:
ticket_no | 请求日期 | 商店 | workers_available |
---|---|---|---|
10000 | 2021-01-03 | 拉尔夫斯 | 真实 |
10001 | 2021-01-08 | 拉尔夫斯 | 真实 |
10002 | 2021-02-05 | 拉尔夫斯 | 假 |
10003 | 2021-04-03 | 拉尔夫斯 | 真实 |
10004 | 2021-01-21 | 本尼的 | 真实 |
10005 | 2021-02-23 | 本尼的 | 假 |
10006 | 2021-04-03 | 本尼的 | 真实 |
我将如何使用 SQL 脚本来解决这个问题?我正在使用 postgresql。我对 LATERAL 连接做了一些研究,但我不太确定如何实现它。
非常感谢提前提供的任何帮助!
要解决这个问题,需要:
使用 INNER JOIN 比较两个表之间的公共标识符,在本例中为 request_date 和 log_date
使用 CASE 表达式创建一个新的
workers_available
列,如果 total_workers 变量大于 0,则设置为 True,否则设置为 false。
因此,这可以通过以下方式完成:
select t1.ticket_no, t1.request_date, t1.store, case when t2.total_workers>0 then 'true' else 'false' end as workers_available from request_log as t1 inner join worker_log as t2 on t1.request_date=t2.log_date;
为了测试这个查询,我从上面的表中创建了两行假设数据 - 一行的 total_workers 大于 0,另一行不是。
select * from request_log;
ticket_no | request_date | store
-----------+---------------------+--------
10000 | 2021-01-03 00:00:00 | Ralphs
10001 | 2021-01-08 00:00:00 | Ralphs
(2 rows)
select * from worker_log;
log_date | total_workers | store
---------------------+---------------+--------
2021-01-03 00:00:00 | 2 | Ralphs
2021-01-08 00:00:00 | 0 | Ralphs
(2 rows)
运行上述查询后,我们可以看到 total_workers=2 的条目为 True,而 total_workers=0 的条目为 False。
select t1.ticket_no, t1.request_date, t1.store, case when t2.total_workers>0 then 'true' else 'false' end as workers_available from request_log as t1 inner join worker_log as t2 on t1.request_date=t2.log_date;
ticket_no | request_date | store | workers_available
-----------+---------------------+--------+-------------------
10000 | 2021-01-03 00:00:00 | Ralphs | true
10001 | 2021-01-08 00:00:00 | Ralphs | false
(2 rows)
请注意,您可能还会发现有关 case 表达式 的教程很有帮助。
您可以像这样通过各自的日期和商店加入2张桌子:
select
r.ticket_no
, r.request_date
, r.store
, case when w.total_workers > 0 then 'true' else 'false' end as workers_available
from request_log as r
inner join worker_log as w on r.request_date = w.log_date
and r.store = w.store
但是有一些重要的假设。日期与显示的完全一致,并且不包含可变时间元素,例如2021-01-03 13:24:35 并且两个表中商店名称的拼写完全相同。
此外,不知道 worker_log 表中的每个商店是否代表每个日期,如果该表可能会跳过 request_log 中找到的任何日期,那么您可能需要一个
left join
而不是像这样:
select
r.ticket_no
, r.request_date
, r.store
, case when coalesce(w.total_workers,0) > 0 then 'true' else 'false' end as workers_available
from request_log as r
left join worker_log as w on r.request_date = w.log_date
and r.store = w.store
如果任何时间戳列确实包含可变时间元素,那么您可以在连接逻辑中使用
date_trunc()
,但这可能会对性能产生负面影响。例如
left join worker_log as w on date_trunc('day',r.request_date) = w.log_date
and r.store = w.store
我还没有看到你的尝试,但试试这个:
select
r.ticket_no,
r.request_date,
r.store,
case
when w.total_workers = 0 then 'false'
when w.total_workers > 0 then 'true'
else 'N/A' end as workers_available
from request_log r
left join
worker_log w
on
r.request_date=w.log_date